我正试图用Swift语言编写一个BMI计算程序。
但是我遇到了这个问题:如何将字符串转换为Double类型?
在Objective-C中,我可以这样做:
double myDouble = [myString doubleValue];
但是在Swift语言中,我应该如何实现?
我正试图用Swift语言编写一个BMI计算程序。
但是我遇到了这个问题:如何将字符串转换为Double类型?
在Objective-C中,我可以这样做:
double myDouble = [myString doubleValue];
但是在Swift语言中,我应该如何实现?
Swift 2 更新
有新的可失败初始化器,可以让您以更习惯化和安全的方式执行此操作(正如许多答案所指出的那样,NSString的double值不太安全,因为它对非数字值返回0。 这意味着"foo"
和"0"
的doubleValue
是相同的。)
let myDouble = Double(myString)
这会返回一个可选项,所以在传递类似"foo"
这样的值时,doubleValue
将返回0,在这种情况下,可失败的初始化程序将返回nil
。您可以使用guard
、if-let
或map
来处理Optional<Double>
。
原始帖子:
您无需像被接受的答案中提出的那样使用NSString构造函数。您可以简单地进行桥接,如下所示:(swiftString as NSString).doubleValue
- [NSString doubleValue]
的结果在Swift中是 Double
而非 Double?
(Optional<Double>
)。这与Swift字符串函数 toInt()
不同,后者返回 Int?
并在文档中说明它只接受与正则表达式 "[-+]?[0-9]+" 匹配的字符串。 - Derrick HathawayDouble.init?(_ text: String)
。 - mixelSwift 4.2+ 字符串转浮点数
你应该使用新的类型初始化器来在字符串和数字类型(Double、Float、Int)之间进行转换。它会返回一个可选类型(Double?),如果字符串不是数字,则该类型将具有正确的值或nil。
注意:不推荐使用NSString的doubleValue属性,因为如果值不能被转换(即:用户输入错误),它将返回0。
let lessPrecisePI = Float("3.14")
let morePrecisePI = Double("3.1415926536")
let invalidNumber = Float("alphabet") // nil, not a valid number
使用if/let解包值并使用它们
if let cost = Double(textField.text!) {
print("The user entered a value price of \(cost)")
} else {
print("Not a valid number: \(textField.text!)")
}
您可以使用NumberFormatter
类来转换格式化的数字和货币。
let formatter = NumberFormatter()
formatter.locale = Locale.current // USA: Locale(identifier: "en_US")
formatter.numberStyle = .decimal
let number = formatter.number(from: "9,999.99")
货币格式
let usLocale = Locale(identifier: "en_US")
let frenchLocale = Locale(identifier: "fr_FR")
let germanLocale = Locale(identifier: "de_DE")
let englishUKLocale = Locale(identifier: "en_GB") // United Kingdom
formatter.numberStyle = .currency
formatter.locale = usLocale
let usCurrency = formatter.number(from: "$9,999.99")
formatter.locale = frenchLocale
let frenchCurrency = formatter.number(from: "9999,99€")
// Note: "9 999,99€" fails with grouping separator
// Note: "9999,99 €" fails with a space before the €
formatter.locale = germanLocale
let germanCurrency = formatter.number(from: "9999,99€")
// Note: "9.999,99€" fails with grouping separator
formatter.locale = englishUKLocale
let englishUKCurrency = formatter.number(from: "£9,999.99")
Double(myString) ?? 0.0
来避免初始化错误。 - Rami AlloushNSFormatter()
而不是强制转换为NSString
,当字符串中不包含Double
值时返回nil
(例如"test"不会返回0.0
)。let double = NSNumberFormatter().numberFromString(myString)?.doubleValue
或者,扩展Swift的String
类型:
extension String {
func toDouble() -> Double? {
return NumberFormatter().number(from: self)?.doubleValue
}
}
并像使用 toInt()
一样使用它:
var myString = "4.2"
var myDouble = myString.toDouble()
这将返回一个可选的 Double?
,需要进行解包。
可以通过强制解包来实现:
println("The value is \(myDouble!)") // prints: The value is 4.2
if let myDouble = myDouble {
println("The value is \(myDouble)") // prints: The value is 4.2
}
更新: 对于本地化,可以按照以下方式将区域设置应用到NSFormatter中:
let formatter = NSNumberFormatter()
formatter.locale = NSLocale(localeIdentifier: "fr_FR")
let double = formatter.numberFromString("100,25")
最后,如果你要处理的是包含货币符号的货币字符串,你可以在格式化器上使用 NSNumberFormatterCurrencyStyle
。
这里的另一个选项是将其转换为NSString
并使用它:
let string = NSString(string: mySwiftString)
string.doubleValue
(swiftString as NSString).doubleValue
。 - CodeSmile这里是一个扩展方法,允许你在 Swift 字符串上调用 doubleValue() 方法并返回一个双精度浮点数(示例输出先显示)
println("543.29".doubleValue())
println("543".doubleValue())
println(".29".doubleValue())
println("0.29".doubleValue())
println("-543.29".doubleValue())
println("-543".doubleValue())
println("-.29".doubleValue())
println("-0.29".doubleValue())
//prints
543.29
543.0
0.29
0.29
-543.29
-543.0
-0.29
-0.29
这里是扩展方法:
extension String {
func doubleValue() -> Double
{
let minusAscii: UInt8 = 45
let dotAscii: UInt8 = 46
let zeroAscii: UInt8 = 48
var res = 0.0
let ascii = self.utf8
var whole = [Double]()
var current = ascii.startIndex
let negative = current != ascii.endIndex && ascii[current] == minusAscii
if (negative)
{
current = current.successor()
}
while current != ascii.endIndex && ascii[current] != dotAscii
{
whole.append(Double(ascii[current] - zeroAscii))
current = current.successor()
}
//whole number
var factor: Double = 1
for var i = countElements(whole) - 1; i >= 0; i--
{
res += Double(whole[i]) * factor
factor *= 10
}
//mantissa
if current != ascii.endIndex
{
factor = 0.1
current = current.successor()
while current != ascii.endIndex
{
res += Double(ascii[current] - zeroAscii) * factor
factor *= 0.1
current = current.successor()
}
}
if (negative)
{
res *= -1;
}
return res
}
}
没有错误检查,但如果需要可以添加它。
从Swift 1.1开始,您可以直接将String
传递给const char *
参数。
import Foundation
let str = "123.4567"
let num = atof(str) // -> 123.4567
atof("123.4567fubar") // -> 123.4567
如果您不喜欢已经废弃的 atof
函数:
strtod("765.4321", nil) // -> 765.4321
一个警告:转换的行为与NSString.doubleValue
不同。
atof
和 strtod
接受以0x
为前缀的十六进制字符串:
atof("0xffp-2") // -> 63.75
atof("12.3456e+2") // -> 1,234.56
atof("nan") // -> (not a number)
atof("inf") // -> (+infinity)
如果您喜欢 .doubleValue
的行为,我们仍然可以使用 CFString
bridging:
let str = "0xff"
atof(str) // -> 255.0
strtod(str, nil) // -> 255.0
CFStringGetDoubleValue(str) // -> 0.0
(str as NSString).doubleValue // -> 0.0
NSString
。 - Sam Soffes我没有看到我想要的答案。我在这里发布我的答案,以帮助其他人。只有当您不需要特定格式时,此答案才有效。
Swift 3
extension String {
var toDouble: Double {
return Double(self) ?? 0.0
}
}
let myDouble = Double("1.1") ?? 0.0
Double.init?(_ text: String)
在 Swift 2.0 中可用。你应该提到这一点。其他答案之所以没有提到,不是因为人们像 Objective-C 开发者那样思考,而是因为此初始化程序早期不可用。 - mixelif let myDouble = NumberFormatter().number(from: yourString)?.doubleValue {
print("My double: \(myDouble)")
}
试试这个:
var myDouble = myString.bridgeToObjectiveC().doubleValue
println(myDouble)
注意:
Beta 5版本已将其移除,不再可用。