首页 > 解决方案 > 为什么 Swift Array contains(_:) 方法必须是非可选的时才接受 nil 参数?

问题描述

我尽可能地简化了我的代码,使它仍然是一个可重现的例子。我认为,当我contains在一系列调用中这样使用它时,它会编译、工作和contains接受nil它不应该的时候。

let array = [1, 2, 3, 4, 5].filter { _ in
    [1, 2, 3].map { smallNumber in
        "\(smallNumber)"
    }
    .contains(nil)
}

但是当我将map结果分配给一个变量然后containsnil值调用时,代码甚至都无法编译。

let array = [1, 2, 3, 4, 5].filter { _ in
    let mappedNumbers = [1, 2, 3].map { smallNumber in
        "\(smallNumber)"
    }
    return mappedNumbers.contains(nil)
}

Xcode 在抱怨'nil' is not compatible with expected argument type 'String',没错。

我希望在第一个示例中出现相同的错误。

标签: iosswift

解决方案


如果上下文需要,编译器可以自动将值包装到可选项中。这就是使简单的任务像

let value: Int? = 123

可能的。在您的第一个示例中,闭包的返回类型是String?从上下文中推断出来的,因此map返回[String?], 和.contains(nil)可以应用于它。即编译器将代码理解为

let array = [1, 2, 3, 4, 5].filter { _ in
    [1, 2, 3].map { smallNumber -> String? in
        "\(smallNumber)"
    }
    .contains(nil)
}

在第二个示例中,编译器没有该上下文,并且mappedNumbers类型为[String]。您可以通过显式指定闭包返回类型来使其编译String?

let array = [1, 2, 3, 4, 5].filter { _ in
    let mappedNumbers = [1, 2, 3].map { smallNumber -> String? in
        "\(smallNumber)"
    }
    return mappedNumbers.contains(nil)
}

推荐阅读