是否有一种在Swift中为类型Double定义扩展以接受字符串作为初始化程序的方法?简单地说,为了找出可行性,我需要这样做:
var double:Double = "one"
println(double) // Outputs "1.0"
我猜它应该与StringLiteralConvertible兼容,但不确定细节。
发布于 2014-12-30 21:44:27
所以,你想要用自然语言解析一个字符串,然后从它生成一个浮点数?
扩展是很容易的部分。只需为其创建一个可失败的初始化程序:
let digits = [
"zero", "one", "two", "three",
"four", "five", "six", "seven",
"eight", "nine",
]
extension Double {
init?(fromEnglishString s: String) {
if let digit = find(digits, s) {
self.init(Double(digit))
}
else {
return nil
}
}
}
let d = Double(fromEnglishString: "one")
// d is {Some 1.0}
最困难的部分是找到一个很好的解析器,可以用英语表达数字(特别是浮点数)。那就更棘手了。您可能会发现这更多的语言不可知论的答案有趣。
您还可以为它编写一个StringLiteralConvertible
扩展。但是,这只是在编译时直接从字符串文本初始化值的时候--这有点没有意义,我的意思是,您真的需要源代码中基于字的数字文字吗?另一个问题是文字可转换初始化程序不能失败,因此您将不得不返回默认值(可能是NaN
?)如果字符串不能被解析。
不过,如果你真的想要的话:
extension Double: StringLiteralConvertible {
public typealias StringLiteralType = String
public typealias UnicodeScalarLiteralType = String
public typealias ExtendedGraphemeClusterLiteralType = String
public init(unicodeScalarLiteral value: UnicodeScalarLiteralType) {
self.init(stringLiteral: value)
}
public init(extendedGraphemeClusterLiteral value: ExtendedGraphemeClusterLiteralType) {
self.init(stringLiteral: value)
}
public init(stringLiteral value: String) {
if let d = Double(fromEnglishString: value) {
self = d
} else {
self = 0.0
}
}
}
let doubleFromLiteral: Double = "three"
// doubleFromLiteral is {Some 3.0}
发布于 2014-12-30 21:44:27
如果你想做你的代码示例所做的事情.编写实现StringLiteralConvertible
协议的扩展。在字面可转换的在NSHipster上有一个很好的记录。
很可能是这样的:
extension Double: StringLiteralConvertible {
convenience init(value: String) {
if value == "one" {
self = 1.0
/*
Add more English-to-number conversion magic here
*/
} else {
return NaN
}
}
}
不仅如此,StringLiteralConvertible
还扩展了一些其他协议,您必须满足这些协议的要求,然后是将英语翻译成数字的整个业务。您可能会遇到一个可行性问题,但是从技术上来说,从字符串中生成Double
是可能的。
最重要的是,对于这是否是一个好主意,还有更多的问题。
https://stackoverflow.com/questions/27712829
复制相似问题