Swift: 如何将String 转换为UInt?

Swift: How to convert String to UInt?

根据Swift - Converting String to Int,有一个String方法toInt()

但是,没有 toUInt() 方法。那么,如何将 String 转换为 Uint

只需使用 UInt 的 init:

let someString = "4"

UInt(someString.toInt()!) // 4

为了不崩溃,请不要使用!来做这个。

很容易在 toInt 的末尾添加一个 map 以将其转换为可选的 UInt:

let str = "4"
let myUInt = str.toInt().flatMap { [=10=] < 0 ? nil : UInt([=10=]) }

然后在 myUInt 上使用

如果您发现自己经常这样做:

extension String {
    func toUInt() -> UInt? {
        return self.toInt().flatMap { [=11=] < 0 ? nil : UInt([=11=]) }
    }
}

let str = "-4"
if let myUInt = str.toUInt() {
    println("yay, \(myUInt)")
}
else {
    println("nuh-uh")
}

编辑:正如@MartinR 指出的那样,虽然安全,但这并没有提取 Int 未涵盖的 UInt 的全部可能值范围,请参阅其他两个答案.

您可能对类似于以下的更安全的解决方案感兴趣:

let uIntString = "4"
let nonUIntString = "foo"

extension String {
    func toUInt() -> UInt? {
        let scanner = NSScanner(string: self)
        var u: UInt64 = 0
        if scanner.scanUnsignedLongLong(&u)  && scanner.atEnd {
            return UInt(u)
        }
        return nil
    }
}

uIntString.toUInt()     // Optional(4)
nonUIntString.toUInt()  // nil

希望对您有所帮助

// 根据@Martin R. 建议编辑

更新 Swift 2/Xcode 7:

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

init?(_ text: String, radix: Int = default)

替换了StringtoInt()方法,所以没有自定义 此任务不再需要代码:

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)

Swift1.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
            }
        }
    }
}

备注:

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

  • 减号测试是必要的,因为 strtoul() 接受 负数(用 相同的位模式)。

  • A Swift 字符串转换为 C 字符串 "behind the scenes" 时 传递给带有 char * 参数的函数,因此可以是 很想打电话给 strtoul(self, &endPtr, 0)(这是我在 这个答案的第一个版本)。问题是自动 创建的 C 字符串只是临时的,当 strtoul() returns, 所以 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)

使用 Forced Unwrapping 或 Optional Binding 确保字符串可以转换为 UInt。 例如:

let string = "123"
let number = UInt(string) //here number is of type *optional UInt*

//Forced Unwrapping

if number != nil {
  //converted to type UInt
}