我正在尝试用swift语言编写一个BMI程序。 我有这个问题:如何转换字符串为双精度?

在Objective-C中,我可以这样做:

double myDouble = [myString doubleValue];

但是如何在Swift语言中实现这一点呢?


当前回答

斯威夫特4

extension String {
    func toDouble() -> Double? {
        let numberFormatter = NumberFormatter()
        numberFormatter.locale = Locale(identifier: "en_US_POSIX")
        return numberFormatter.number(from: self)?.doubleValue
    }
}

其他回答

另一个选项是将this转换为NSString并使用它:

let string = NSString(string: mySwiftString)
string.doubleValue

下面是一个扩展方法,允许你简单地调用doubleValue()在一个Swift字符串上,并得到一个双返回(示例输出先来)

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 3中,您可以使用:

if let myDouble = NumberFormatter().number(from: yourString)?.doubleValue {
   print("My double: \(myDouble)")
}

注意: —如果字符串中包含除数字、适合区域设置的组或小数分隔符以外的任何字符,解析将失败。 —忽略字符串中任何开头或结尾的空格分隔符。例如,字符串“5”、“5”和“5”都产生数字5。

摘自文档: https://developer.apple.com/reference/foundation/numberformatter/1408845-number

我发现更可读添加一个扩展字符串如下:

extension String {
    var doubleValue: Double {
        return (self as NSString).doubleValue
    }
}

然后你就可以写代码了:

myDouble = myString.doubleValue

这是基于@Ryu的回答

只要你在一个用圆点作为分隔符的国家,他的解决方案就很好。默认情况下NSNumberFormatter使用设备区域设置。因此,在所有使用逗号作为默认分隔符的国家(包括法国的@PeterK),这将失败。如果数字使用点作为分隔符(通常情况下)。要将这个NSNumberFormatter的区域设置为US,并使用圆点作为分隔符替换行

return NSNumberFormatter().numberFromString(self)?.doubleValue

with

let numberFormatter = NSNumberFormatter()
numberFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
return numberFormatter.numberFromString(self)?.doubleValue

因此,完整的代码变成

extension String {
    func toDouble() -> Double? {
        let numberFormatter = NSNumberFormatter()
        numberFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
        return numberFormatter.numberFromString(self)?.doubleValue
    }
}

要使用它,只需调用"Your text goes here".toDouble()

这将返回一个可选的Double?

正如@Ryu提到的,你可以强制展开:

println("The value is \(myDouble!)") // prints: The value is 4.2

或者使用if let语句:

if let myDouble = myDouble {
    println("The value is \(myDouble)") // prints: The value is 4.2
}