R) { prin-6ren">
gpt4 book ai didi

Swift:通用重载, "more specialized"的定义

转载 作者:行者123 更新时间:2023-12-04 09:39:38 25 4
gpt4 key购买 nike

在下面的例子中,为什么 foo(f)叫暧昧?
我知道第二个重载也适用于 P == () ,
但为什么第一个不被认为更专业,
因此更好的匹配?

func foo<R>(_ f: () -> R) { print("r") }
func foo<P, R>(_ f: (P) -> R) { print("pr") }

let f: () -> Int = { 42 }
foo(f) // "Ambiguous use of 'foo'"

最佳答案

我会说你的问题是你没有 explicitely告诉编译器 P == ()
在操场上尝试以下代码:

Void.self == (Void).self // true
Void() == () // true
(Void)() == () // true
(Void) == () // Cannot convert value of type '(Void).Type' to expected argument type '()'

Foo<Int>.self == (() -> Int).self // false
(() -> Int).self == ((Void) -> Int).self // false
Foo<Int>.self == ((Void) -> Int).self // true


(Void)无法转换为 () , 我猜编译器看不懂 foo<R>(_ f: () -> R)实际上是 foo<P, R>(_ f: (P) -> R)的专业.

我建议你创建 generic type aliases对于您的函数类型,以帮助编译器了解您在做什么,例如。 :
typealias Bar<P, R> = (P) -> R
typealias Foo<R> = Bar<Void, R>

现在你可以像这样定义你的函数:
func foo<R>(_ f: Foo<R>) { print("r") } // Note that this does not trigger a warning.
func foo<P, R>(_ f: Bar<P, R>) { print("pr") }

然后将它们与您想要的任何闭包一起使用:
let f: () -> Int = { 42 }
foo(f) // prints "r"
let b: (Int) -> Int = { $0 }
foo(b) // prints "pr"
let s: (String) -> Double = { _ in 0.0 }
foo(s) // prints "pr"


但你实际上可以只写:
func foo<R>(_ f: (()) -> R) { print("r") }
func foo<P, R>(_ f: (P) -> R) { print("pr") }

甚至 :
func foo<R>(_ f: (Void) -> R) { print("r") } // triggers warning :
// When calling this function in Swift 4 or later, you must pass a '()' tuple; did you mean for the input type to be '()'?
func foo<P, R>(_ f: (P) -> R) { print("pr") }

你会得到相同的结果。

关于Swift:通用重载, "more specialized"的定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62383640/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com