混淆错误:地图变量的可选性将其从单个对象更改为数组 [英] Confusing error: Optionality of map's variable changes it from single object to array

查看:139
本文介绍了混淆错误:地图变量的可选性将其从单个对象更改为数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有:

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

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