在map()中使用init() [英] Using init() in map()
问题描述
为什么这行不通?
"abcdefg".characters.map(String.init) // error: type of expression is ambiguous without more context
详细信息
我在Swift中喜欢的一件非常酷的事情是能够通过传入init方法(假设存在该类型的init()
)将一件事物的集合转换为另一件事物的能力.
Details
One really cool thing I like in Swift is the ability to convert a collection of one thing to another by passing in an init method (assuming an init()
for that type exists).
这里是将元组列表转换为ClosedInterval
实例的示例.
Here's an example converting a list of tuples to instances of ClosedInterval
.
[(1,3), (3,4), (4,5)].map(ClosedInterval.init)
该示例还利用了以下事实:只要该元组与函数的参数列表匹配,我们就可以将一个参数元组作为单个参数传递.
That example also takes advantage of the fact that we can pass a tuple of arguments as a single argument as long as the tuple matches the function's argument list.
这是另一个示例,这次将数字列表转换为字符串实例.
Here another example, this time converting a list of numbers to string instances.
(1...100).map(String.init)
不幸的是,下一个示例不起作用.在这里,我试图将一个字符串拆分为一个单字符字符串列表.
Unfortunately, the next example does not work. Here I am trying to split up a string into a list of single-character strings.
"abcdefg".characters.map(String.init) // error: type of expression is ambiguous without more context
map()
应该在Character
的列表上进行操作(确实,我能够在操场上验证Swift会在此处将[Character]的正确类型传递给map
).
map()
should be operating on a list of Character
(and indeed I was able to verify in a playground that Swift infers the correct type of [Character] here being passed into map
).
String
绝对可以从Character
实例化.
let a: Character = "a"
String(a) // this works
有趣的是,如果每个字符都在各自的数组中,则此方法有效.
And interestingly, this works if the characters are each in their own array.
"abcdefg".characters.map { [$0] }.map(String.init)
或等价物:
let cx2: [[Character]] = [["a"], ["b"], ["c"], ["d"]]
cx2.map(String.init)
我知道我可以做到:
"abcdefg".characters.map { String($0) }
但是我专门试图理解为什么"abcdefg".characters.map(String.init)
不起作用(IMO这种语法也更易读和优雅)
But I am specifically trying to understand why "abcdefg".characters.map(String.init)
does not work (IMO this syntax is also more readable and elegant)
推荐答案
简化的复制:
String.init as Character -> String
// error: type of expression is ambiguous without more context
这是因为String
有两个接受一个Character
的初始化程序:
This is because String
has two initializers that accept one Character
:
init(_ c: Character)
init(stringInterpolationSegment expr: Character)
据我所知,使用初始值设定项作为值时,无法消除它们的歧义.
As far as I know, there is no way to disambiguate them when using the initializer as a value.
对于(1...100).map(String.init)
,String.init
被称为Int -> String
.尽管有两个初始化程序接受一个Int
:
As for (1...100).map(String.init)
, String.init
is referred as Int -> String
. Although there are two initializers that accept one Int
:
init(stringInterpolationSegment expr: Int)
init<T : _SignedIntegerType>(_ v: T)
通用类型比显式类型更弱.因此,在这种情况下,编译器选择stringInterpolationSegment:
一个.您可以通过命令确认并点击.init
.
Generic type is weaker than explicit type. So the compiler choose stringInterpolationSegment:
one in this case. You can confirm that by command + click on .init
.
这篇关于在map()中使用init()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!