我想做这样的事情:
var x = ["10","20",30"]
var y = x.map(Int.init)
但我收到此错误
对成员' init()'
的模糊引用
我知道我可以写
var y = x.map { Int($0) }
但我想知道是否还有其他办法。
答案 0 :(得分:5)
问题是,Int
初始化程序不存在仅 String
参数。
init?(_ text: String, radix: Int = default)
虽然radix:
参数有一个默认值,但只有编译器在初始化程序的调用站点为您“填写”。
获取对函数本身的引用时,不会部分应用默认参数值,编译器也不会为所有可能的默认参数值组合生成额外的重载。后者不仅会给您的代码增加大量膨胀,而且两个选项都会破坏依赖于在呼叫站点插入的默认参数值(例如#file
& #line
)。
为了使其正常工作,函数值本身必须支持默认参数值,这带来了相当多的复杂性。虽然很可能是语言的未来版本支持的东西。
获得所需行为的一个简单解决方案是在Int
上添加一个扩展程序,该扩展程序会添加init(_:)
初始化程序,然后转发到init(_:radix:)
:
extension Int {
/// Creates a new integer value from the given base-10 integer string, returning nil
/// if the string is in an invalid format.
init?(_ string: String) {
// we're saying (_:radix:) in order to disambiguate the call, the compiler
// will insert the default parameter value of radix: for us.
self.init(_:radix:)(string)
}
}
在Swift 4中注意,这可能是FixedWidthInteger
的扩展,它为标准库的整数类型提供init(_:radix:)
的实现。
现在你可以说:
let x = ["10", "20", "30"]
let y = x.map(Int.init) // [Optional(10), Optional(20), Optional(30)]
因为Int.init
现在指的是我们的扩展程序初始化程序。
这也适用于flatMap(_:)
:
let y = x.flatMap(Int.init) // [10, 20, 30]
还将过滤转换中的nil
元素(不可转换为整数的字符串)。
答案 1 :(得分:1)
问题归结为无法将具有默认参数的函数(例如Int.init(_ text: String, radix: Int = default)
)分配给只有在默认参数“不存在”时才能“适合”的地方。
当您自己关闭{ Int($0) }
时,您告诉编译器您希望应用radix
的默认值。不幸的是,这不会隐含地发生。