简体   繁体   English

为什么 Swift Array contains(_:) 方法在必须是非可选参数时接受 nil 参数?

[英]Why does Swift Array contains(_:) method accept nil argument when it must be non-optional?

I simplified my code as much as I could to make it still be a reproducible example.我尽可能地简化了我的代码,以使其仍然是一个可重现的示例。 When I use contains like this in a chain of calls it does compile, work and contains accepts nil when it shouldn't, I think.当我在调用链中使用这样的contains时,它会编译、工作并且contains在不应该的时候接受nil ,我想。

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

But when I assign map result to a variable and then call contains with nil value the code doesn't even compile.但是,当我将map结果分配给一个变量,然后使用nil值调用contains时,代码甚至无法编译。

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

Xcode is complaining about 'nil' is not compatible with expected argument type 'String' , that is right. Xcode 抱怨'nil' is not compatible with expected argument type 'String' ,没错。

I expect the same error in the first example.我希望在第一个示例中出现相同的错误。

The compiler can automatically wrap a value into an optional, if required by the context.如果上下文需要,编译器可以自动将值包装到可选值中。 That is what makes simple assignments like这就是让简单的任务像

let value: Int? = 123

possible.可能的。 In your first example, the return type of the closure is inferred as String?在您的第一个示例中,闭包的返回类型被推断为String? from the context, so that the map returns [String?] , and .contains(nil) can be applied to it.从上下文中,以便map返回[String?] ,并且.contains(nil)可以应用于它。 Ie the compiler understands the code as即编译器将代码理解为

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

In the second example the compiler does not have that context, and mappedNumbers has the type [String] .在第二个示例中,编译器没有该上下文,并且mappedNumbers具有类型[String] You can make it compile by specifying the closure return type String?您可以通过指定闭包返回类型String? explicitly:明确地:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM