我想做这样的事情:
var x = ["10","20",30"] var y = x.map(Int.init)
但是我得到这个错误
对成员’init()’的不明确引用
我知道我可以写
var y = x.map { Int($0) }
但是我想知道是否还有另一种方式。
问题在于不存在 仅 具有参数的Int初始化程序。 __String
Int
String
目前只存在:
init?(_ text: String, radix: Int = default)
尽管该radix:参数具有默认值,但是编译器仅在初始化程序的调用位置为您“填充”该默认值。
radix:
获取对函数本身的引用时,不会部分应用默认参数值,编译器也不会为默认参数值的所有可能组合生成额外的重载。后者不仅会给您的代码增加很大的膨胀,而且这两个选项都会破坏默认参数值,该默认参数值取决于在调用站点处插入的值(例如#file&#line)。
#file
#line
为了使其正常工作,函数值本身必须支持默认参数值,这带来了相当大的复杂性。尽管这可能是该语言的未来版本所支持的东西。
一种获得所需行为的简单解决方案是只编写一个扩展,在Int其上添加一个init(_:)初始化程序,然后将其转发到init(_:radix:):
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:)了标准库的整数类型的实现。
FixedWidthInteger
现在您可以说:
let x = ["10", "20", "30"] let y = x.map(Int.init) // [Optional(10), Optional(20), Optional(30)]
因为Int.init现在是指我们的扩展初始化器。
Int.init
这也适用于flatMap(_:):
flatMap(_:)
let y = x.flatMap(Int.init) // [10, 20, 30]
这也会nil从转换中过滤掉元素(不可转换为整数的字符串)。
nil