gpt4 book ai didi

swift - 如何测试字符串的可选性?

转载 作者:可可西里 更新时间:2023-11-01 01:06:06 24 4
gpt4 key购买 nike

我有两种不同的场景需要测试可选类型的“可选性”。除了使用笨拙的 switch 语句之外,我一直无法弄清楚如何显式测试变量是 .None 还是 .Some .如何使用 if 语句测试 Someness

场景一

我正在写一个地址格式化程序,我的输入是一些字符串?类型。在此示例中,对 (str != nil) 的简单测试将起作用。但是,由于我的另一个需要是在处理“双重可选”和 nil 测试时无法区分 .Some(.None).None 的解决方案这个问题也将解决那个问题。

这是一个使用开关

的版本
let address1:String? = "123 Main St"
let address2:String? = nil
let apt:String? = "101"

let components = [address1, address2, apt].filter( { (c) -> Bool in
switch c {
case .Some: return true
case .None: return false
}
}).map { return $0! } //Had to map because casting directly to [String] crashes
print(", ".join(components)) //"123 Main St, 101"

我想看到的是类似 if 的东西:

let nice = ["123 Main St", nil, "303"].filter { (c) -> Bool in
return (c == .Some)
}
print(", ".join(nice))

场景2

这就是 nil 测试不起作用的地方。如果某物是字符串??它可以是 .None.Some(.None).Some(.Some(String)) 中的任何一个。在我的例子中,变量携带来自 api 调用的 recordID,它可能完全丢失 (.None),一个值 (.Some(.Some("ABDEFG")),或显式 NULL (.Some(.None))。

let teamNoneNone: String?? = .None
let teamSomeNone: String?? = .Some(.None)
let teamSomeSome: String?? = "My favorite local sportsball team"

if teamNoneNone == nil {
print("teamNoneNone is nil but is it .None? We don't know!") //prints
} else {
print("teamNoneNone is not nil")
}

if teamSomeNone == nil {
print("teamSomeNone is nil")
} else {
print("teamSomeNone is not nil but is it .Some(.None)? We don't know!") //prints
}

if teamSomeSome == nil {
print("teamSomeSome is nil but is it .None? We don't know!")
} else {
print("teamSomeSome is not nil but is it .Some(.None) or .Some(.Some())? We don't know!") //prints
}

通过另一篇 SO 帖子,我找到了这样的解决方法,但不太清楚普通读者会发生什么:

if let team: String? = teamSomeNone {
print("teamSomeNone is Some(.None)") //prints
} else {
print("teamSomeNone is .Some(.Some())")
}

最佳答案

if let 测试一个值是否为 .None,如果不是,则解包并将其绑定(bind)到 if 语句中的局部变量。

将 switch 与 .Some.None 一起使用实际上是处理可选值的次要方法,如果 if let 没有削减它。但它几乎总是如此,尤其是现在您可以在一条语句中执行多个 if let,在最新版本的 Swift 1.2 投入生产之后。

想要过滤掉集合中的 nils 是一项非常常见的任务,Haskell 为其提供了一个标准函数,称为 catMaybe。这是一个版本,我将其称为 catSome,它可以在 Swift 中实现这一目的:

func catSome<T>(source: [T?]) -> [T] {
var result: [T] = []
// iterate over the values
for maybe in source {
// if this value isn’t nil, unwrap it
if let value = maybe {
// and append it to the array
result.append(value)
}
}
return result
}

let someStrings: [String?] = ["123 Main St", nil, "101"]

catSome(someStrings) // returns ["123 Main St", "101"]

双重包装的可选值有点麻烦,所以最好的解决方案是首先避免它们——通常是通过使用可选链或 flatMap

但是如果你确实发现自己有一些东西,而你只关心内在值(value),你可以使用双 if let 展开它们:

// later parts of the let can rely on the earlier
if let outer = teamSomeSome, teamName = outer {
println("Fully unwrapped team is \(teamName)")
}

如果您想明确知道一个双可选是否在外部值中有一个内部 nil,但 nil 本身不是,您可以使用 if let 带有 where 子句:

if let teamSomeMaybe = teamSomeNone where teamSomeMaybe == nil {
// this will be executed only if it was .Some(.None)
println("SomeNone")
}

where 子句是一个额外的条件,可以应用于展开的值。

关于swift - 如何测试字符串的可选性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29687743/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com