在Swift中将可选字符串转换为可选整数的最简单方法

9
我认为在Swift中应该有一种简单的方法可选地将String转换为Int,但我想不出来。 value是一个String?,我需要返回一个Int?
基本上我想做到这一点,但没有样板:guard let intValue = Int(value ?? "") else { return nil }
return value != nil ? Int(value) : nil

我尝试了这个方法,看起来符合Swift的规范,简洁明了。但是它不能识别语法:
return Int?(value)

2
Int(value ?? "") 怎么样? - vacawama
是的,这样更好。对我来说很奇怪的是,初始化程序不接受可选项,如果传入任何nil值,它就会返回nil。我猜Swift的类型系统会心脏病发作。 - devios1
我更新了我的答案,加入了一个Int扩展,可以做到这一点。 - vacawama
3个回答

11
你可以使用nil合并运算符??来展开String?并使用默认值"",你知道它会产生nil
return Int(value ?? "")

另一种方法:接受String?的Int初始化器

来自评论:

如果初始化器不接受可选值,并且仅在传入任何nil时返回nil,这对我来说非常奇怪。

您可以为Int创建自己的初始化器,以实现此功能:

extension Int {
    init?(_ value: String?) {
        guard let value = value else { return nil }
        self.init(value)
    }
}

现在你可以这样做:

var value: String?
return Int(value)

1
我认为这是正确的方法,并且具有更好的可读性。 - Leo Dabus
1
nil 同化方法确实简洁易读,但我认为值得指出的是,相对于 nil 同化方法,如果 value 为空,flatMap(_:) 方法(而非 nil 同化方法)不会调用肯定失败的调用(传递字面量 "" 到可失败的 Int(由 String)初始化程序)。出于这个原因,我认为 flatMap(_:) 方法或上面的第二种方法(自定义初始化程序)比 nil 同化方法更值得推荐。 - dfrib
1
自定义初始化方法可以稍微简化一下,改为guard let value = value else { return nil }; self.init(value) - Martin R
可以的。谢谢@MartinR! - vacawama
这真的很酷。我没有意识到你可以在扩展中添加自定义初始化器! - devios1

9
你可以使用 OptionalflatMap() 方法:
func foo(_ value: String?) -> Int? {
    return value.flatMap { Int($0) }
}

如果value == nil,则flatMap返回nil。否则,它会计算Int($0),其中$0是已解包的值,并返回结果(如果转换失败,则可能是nil):
print(foo(nil) as Any)      // nil
print(foo("123") as Any)    // Optional(123)
print(foo("xyz") as Any)    // nil

map 也是一样的。 - Sulthan
@Sulthan:value.map { Int($0) } 将会得到一个嵌套的可选项,例如 Optional(Optional(123))。 - Martin R
@MartinR 是的,你说得对,我没意识到里面有可选项! - Sulthan

4
使用字符串扩展,您不必担心字符串等于 nil。
extension String {
  func toInt() -> Int? {
    return Int(self)
  }
}

使用方法:

var nilString: String?
print("".toInt())         // nil
print(nilString?.toInt()) // nil
print("123".toInt())      // Optional(123)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接