根据Swift - Converting String to Int,有一个String
方法toInt()
。
但是,没有toUInt()
办法。那么,如何将 a 转换String
为 a Uint
?
根据Swift - Converting String to Int,有一个String
方法toInt()
。
但是,没有toUInt()
办法。那么,如何将 a 转换String
为 a Uint
?
Swift 2/Xcode 7 的更新:
从 Swift 2 开始,所有整数类型都有一个(可失败的)构造函数
init?(_ text: String, radix: Int = default)
它替换了 的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)
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
}
}
}
}
评论:
BSD 库函数strtoul
用于转换。endPtr
设置为输入字符串中的第一个“无效字符”,因此如果所有字符都可以转换,endPtr.memory == 0
则必须保留。在转换错误的情况下,全局变量被设置为非零值(例如溢出)。errno
ERANGE
负号测试是必要的,因为strtoul()
它接受负数(使用相同的位模式转换为无符号数)。
当传递给带参数的函数时,Swift 字符串会“在幕后”转换为 C 字符串char *
,因此可能会被诱惑调用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)
您可能对类似于以下的更安全的解决方案感兴趣:
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. 的建议编辑
请,为了不崩溃的爱,不!
要这样做。
很容易map
在末尾添加 atoInt
以将其转换为可选的UInt
:
let str = "4"
let myUInt = str.toInt().flatMap { $0 < 0 ? nil : UInt($0) }
然后在. _myUInt
如果你发现自己经常这样做:
extension String {
func toUInt() -> UInt? {
return self.toInt().flatMap { $0 < 0 ? nil : UInt($0) }
}
}
let str = "-4"
if let myUInt = str.toUInt() {
println("yay, \(myUInt)")
}
else {
println("nuh-uh")
}
编辑:正如@MartinR 指出的那样,虽然安全,但这并没有提取未涵盖的全部可能值UInt
,Int
请参阅其他两个答案。
使用 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
}
只需使用 UInt 的初始化:
let someString = "4"
UInt(someString.toInt()!) // 4