在map()中使用init() [英] Using init() in map()

查看:334
本文介绍了在map()中使用init()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么这行不通?

"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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆