混淆错误:地图变量的可选性将其从单个对象更改为数组 [英] Confusing error: Optionality of map's variable changes it from single object to array
问题描述
我有:
private var wrappedObjects: [WrapperClass]?
var objects: [SomeClass]?
{
didSet
{
self.wrappedObjects = objects.map{ WrapperClass($0) }
}
}
这将导致以下错误:
`Cannot convert value of type '[SomeClass]' to expected argument type 'SomeClass'`
但是,当我只是更改一行到:
However when I just change one line to:
var objects: [SomeClass] = []
错误消失了。
为什么对象
使映射
认为 $ 0
是单个 SomeClass
或数组 [SomeClass]
Why does the optionality of objects
makes map
think $0
is either a single SomeClass
or an array [SomeClass]
respectively?
推荐答案
这里的问题是有两个 map(_:)
函数。 一个序列:
The problem here is that there are two map(_:)
functions. One for sequences:
public protocol Sequence {
// ...
/// Returns an array containing the results of mapping the given closure
/// over the sequence's elements.
///
/// - Parameter transform: A mapping closure. `transform` accepts an
/// element of this sequence as its parameter and returns a transformed
/// value of the same or of a different type.
/// - Returns: An array containing the transformed elements of this
/// sequence.
func map<T>(_ transform: (Iterator.Element) throws -> T) rethrows -> [T]
// ...
}
和一个用于可选项:
public enum Optional<Wrapped> : ExpressibleByNilLiteral {
// ...
/// Evaluates the given closure when this `Optional` instance is not `nil`,
/// passing the unwrapped value as a parameter.
///
/// - Parameter transform: A closure that takes the unwrapped value
/// of the instance.
/// - Returns: The result of the given closure. If this instance is `nil`,
/// returns `nil`.
public func map<U>(_ transform: (Wrapped) throws -> U) rethrows -> U?
// ...
}
所以当你在 [SomeClass]?
之间调用地图
,第二个地图
函数将被使用,其中转换函数参数将是类型为 [SomeClass]
,因为 map
将打开它对于您,并对其进行转换。
Therefore when you call map
on a [SomeClass]?
, the second map
function will be used, where the transformation function parameter will be of type [SomeClass]
, as map
will unwrap it for you, and apply a given transformation to it.
但是,当您在$ $ c上调用 map
$ c> [SomeClass] ,将使用第一个映射
函数,其中元素将被迭代遍历 - 将转换函数应用于他们。因此,转换函数的参数类型将为 SomeClass
。
However, when you call map
on a [SomeClass]
, the first map
function will be used, where the elements will be iterated through – applying the transformation function to each of them. Therefore the parameter type of the transformation function will be SomeClass
.
因此,一个有趣的解决方案是使用 map
两次 - 一次解开,一次对元素进行转换:
One amusing solution therefore would be to use map
twice – once to unwrap, once to apply a transform to the elements:
self.wrappedObjects = objects.map{ $0.map{ WrapperClass($0) } }
但是,这是绝对可笑的,你一定要使用可选的链接作为Rob建议。
However, this is absolutely ridiculous, you should definitely use optional chaining as Rob suggests.
这篇关于混淆错误:地图变量的可选性将其从单个对象更改为数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!