swift - 在 Swift 中通过函数传递泛型类型

标签 swift generics

为了避免代码重复,我正在尝试找到一种方法来推断参数类型 T() -> T来自 U 类型的变量.

我不知道我是否足够清楚,所以这是我不想做的:

func f<T>(closure: () -> T) -> String {
    return "closure: () -> \(T.self)"
}
func f<T>(value: T) -> String {
    return "value: \(T.self)"
}

f("test1") // -> "value: Swift.String"
f({ return "test2" }) // -> "closure: () -> Swift.String"

func foo<U>(bar: U) -> (String, String) {
    return ("\(U.self)", f(bar))
}

foo("test3") // (.0 "Swift.String", .1 "value: Swift.String")
foo({ return "test4" }) // (.0 "() -> Swift.String", .1 "value: () -> Swift.String")

我预计foo({ return "test4" })调用f<T>(closure: () -> T)函数而不是 f<T>(value: T) 。为什么 Swift 无法推断 bar: U() -> T 匹配模式?

最佳答案

TL;DR: foo()/U 导致类型数据丢失。

我怀疑您有 C++ 背景。

这在 C++ 中可以工作,因为 C++ 根据调用站点推断类型。但 Swift 有所不同,因为泛型参数是类型数据的唯一来源。在您的情况下,您没有提供有关类型 U 的信息,因此编译器不知道如何将其转换为闭包类型。您对 f() 的值覆盖有效,因为您没有在 T 上放置任何条件,而在闭包类型覆盖中,您指定了特定的形式(闭包)。由于通过采用通用(空白)类型 U 的 foo 调用会丢失所有类型数据,因此编译器没有足够的信息,并且无法推断出从(空白)到闭包的转换。

这是“类型具体化”的主题,devforums.apple.com 上对此有很长的讨论。

关于swift - 在 Swift 中通过函数传递泛型类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28627566/

相关文章:

swift - Swiftui [BUG] NavigationView和列表仅在iPad模拟器上不显示

ios - 如何在可移动的两个UIView之间重新绘制连线

ios - 如何要求泛型类型使用协议(protocol)中的特定类型实现泛型协议(protocol)

c# - 通过 C# 中扩展方法的反射获取泛型重载

android - 如何在Kotlin扩展功能中使用泛型

c# - 如何在封闭泛型类型上获取泛型方法,从开放泛型类型打开 MethodInfo?

ios - 为什么无法发现特定的 BLE 外设服务?

swift - 如何将 Swift 字典公开为键值对的类型化序列?

swift - 从 Swift 中协议(protocol)定义的函数返回泛型

Swift 如何从条件绑定(bind)必须具有可选类型的 do catch 返回元组?