问题描述
根据 Swift-将字符串转换为Int ,有一种String
方法toInt()
.
但是,没有toUInt()
方法.那么,如何将String
转换为Uint
?
But, there's no toUInt()
method. So, how to convert a String
to a Uint
?
推荐答案
Swift 2/Xcode 7更新:
从Swift 2开始,所有整数类型都有一个(失败的)构造函数
As of Swift 2, all integer types have a (failable) constructor
init?(_ text: String, radix: Int = default)
替换了String
的toInt()
方法,因此没有自定义此任务不再需要代码:
which replaces the toInt()
method of String
, so no customcode is needed anymore for this task:
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
的完整范围,并正确检测所有可能的错误(例如溢出或尾随无效字符):
This looks a bit complicated, but should work for all numbers in thefull range of UInt
, and detect all possible errors correctly(such as overflow or trailing invalid characters):
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
表示溢出).
The BSD library function
strtoul
is used for the conversion.TheendPtr
is set to first "invalid character" in the input string,thereforeendPtr.memory == 0
must be hold if all characterscould be converted.In the case of a conversion error, the globalerrno
variable is setto a non-zero value (e.g.ERANGE
for an overflow).
必须测试负号,因为strtoul()
接受负数(使用负号转换为无符号数)相同的位模式).
The test for a minus sign is necessary because strtoul()
acceptsnegative numbers (which are converted to the unsigned number with thesame bit pattern).
在以下情况下,Swift字符串将转换为幕后"的C字符串:传递给带有char *
参数的函数,因此可能是试图调用strtoul(self, &endPtr, 0)
(这是我在此答案的第一个版本).问题是自动创建的C字符串只是临时的,在以下情况下可能已经无效strtoul()
返回,因此endPtr
不会指向输入字符串中的字符不再存在.这是我在Playground中测试代码时发生的.使用self.withCString { ... }
,不会发生此问题,因为C字符串在整个执行过程中都是有效的
A Swift string is converted to a C string "behind the scenes" whenpassed to a function taking a char *
parameter, so one could betempted to call strtoul(self, &endPtr, 0)
(which is what I did inthe first version of this answer). The problem is that the automaticallycreated C string is only temporary and can already be invalid whenstrtoul()
returns, so that endPtr
does not point to acharacter in the input string anymore. This happened when I tested the code in the Playground. With self.withCString { ... }
, this problem does not occur because the C string is valid throughout the executionof the closure.
一些测试:
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)
这篇关于Swift:如何将String转换为UInt?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!