Swift:如何将String转换为UInt?

ma1*_*w28 9 string type-conversion uint swift

根据Swift - 将字符串转换为Int,有一种String方法toInt().

但是,没有toUInt()方法.那么,如何将a转换StringUint

Mar*_*n R 13

Swift 2/Xcode 7的更新:

从Swift 2开始,所有整数类型都有一个(可用的)构造函数

init?(_ text: String, radix: Int = default)
Run Code Online (Sandbox Code Playgroud)

它取代了toInt()方法String,因此不再需要自定义代码来执行此任务:

print(UInt("1234")) // Optional(1234)
// This is UInt.max on a 64-bit platform:
print(UInt("18446744073709551615")) // Optional(18446744073709551615)
print(UInt("18446744073709551616")) // nil (overflow)
print(UInt("1234x")) // nil (invalid character)
print(UInt("-12")) // nil (invalid character)
Run Code Online (Sandbox Code Playgroud)

Swift 1.x的旧答案:

这看起来有点复杂,但应该适用于整个范围内的所有数字UInt,并正确检测所有可能的错误(例如溢出或尾随无效字符):

extension String {
    func toUInt() -> UInt? {
        if contains(self, "-") {
            return nil
        }
        return self.withCString { cptr -> UInt? in
            var endPtr : UnsafeMutablePointer<Int8> = nil
            errno = 0
            let result = strtoul(cptr, &endPtr, 10)
            if errno != 0 || endPtr.memory != 0 {
                return nil
            } else {
                return result
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

备注:

  • BSD库函数strtoul用于转换.该endPtr设置为输入字符串第一个"无效字符",因此endPtr.memory == 0必须保持如果所有的字符可以转换.在转换错误的情况下,全局errno变量被设置为非零值(例如ERANGE,对于溢出).

  • 负号的测试是必要的,因为strtoul()接受负数(用相同的位模式转换为无符号数).

  • 当传递给带char *参数的函数时,Swift字符串被转换为"幕后"的C字符串,因此可以尝试调用strtoul(self, &endPtr, 0)(这是我在本答案的第一个版本中所做的).问题是自动创建的C字符串只是临时的,并且在strtoul()返回时可能已经无效 ,因此endPtr不再指向输入字符串中的字符.这发生在我在Playground中测试代码时.使用self.withCString { ... },不会发生此问题,因为C字符串在整个闭包执行期间有效.

一些测试:

println("1234".toUInt()) // Optional(1234)
// This is UInt.max on a 64-bit platform:
println("18446744073709551615".toUInt()) // Optional(18446744073709551615)
println("18446744073709551616".toUInt()) // nil (overflow)
println("1234x".toUInt()) // nil (invalid character)
println("-12".toUInt()) // nil (invalid character)
Run Code Online (Sandbox Code Playgroud)