extension UIViewController {
class func doSomething<T: UIView>() -> T {
return T()
}
class func doSomethingElse<T: UIView>(value: T) {
// Note: value is a instance of T
}
class func doLastThing<T: UIView>(value: T.Type) {
// Note: value is a MetaType of T
}
}
之后,我们必须在调用时提供T。
let result = UIViewController.doSomething() as UIImageView // Define `T` by casting, as UIImageView
let result: UILabel = UIViewController.doSomething() // Define `T` with property type, as UILabel
UIViewController.doSomethingElse(value: UIButton()) // Define `T` with parameter type, as UIButton
UIViewController.doLastThing(value: UITextView.self) // Define `T` with parameter type, as UITextView
8条答案
按热度按时间pengsaosao1#
这里不需要泛型,因为这里有静态类型(String作为参数),但是如果你想让泛型函数调用另一个泛型函数,你可以执行以下操作。
使用泛型方法
使用泛型类(灵活性较低,因为每个示例只能为1个类型定义泛型)
x8diyxa72#
我认为当你指定泛型函数时,你应该指定一些类型T的参数,如下所示:
如果你想调用handle()方法,那么你可以通过编写协议,并为T指定类型约束来实现:
因此可以使用String调用此泛型函数:
它会编译
vdzxcuhz3#
到目前为止,我个人的最佳实践是使用@orkhan-alikhanov的答案。今天,当我研究SwiftUI以及
.modifier()
和ViewModifier
是如何实现的时,我发现了另一种方法(或者说它更像是一种变通方法?)只需将第二个函数 Package 到
struct
中。示例:
如果这个函数给你“不能显式专用化泛型函数”
下面这个可能会有帮助。将
generic1
的声明 Package 成struct
:并调用它:
备注:
struct
的解决方法是一个很好的例子。这里的解决方法没有更多的信息-但是通过了编译器。相同的信息,但是不同的结果?那么一定是出了问题。如果是编译器错误,它可以得到修复。k97glaaz4#
我的泛型类函数
class func retrieveByKey<T: GrandLite>(key: String) -> T?
也有类似的问题。我不能称之为
let a = retrieveByKey<Categories>(key: "abc")
,因为类别是GrandLite的子类。let a = Categories.retrieveByKey(key:"abc")
返回了GrandLite,而不是Categories。泛型函数不会基于调用它们的类来推断类型。class func retrieveByKey<T: GrandLite>(aType: T, key: String>) -> T?
给了我一个错误,当我尝试let a = Categories.retrieveByKey(aType: Categories, key: "abc")
给了我一个错误,它不能转换类别。类型到GrandLite,即使类别是GrandLite的子类。但是...class func retrieveByKey<T: GrandLite>(aType: [T], key: String) -> T?
did work如果我尝试let a = Categories.retrieveByKey(aType: [Categories](), key: "abc")
,显然子类的显式赋值不起作用,但是使用另一个泛型类型(数组)的隐式赋值在Swift 3中起作用。gcxthw6b5#
由于在Swift中以
generic<T>()
的身份调用是非法的,这种
generic(of: T.self)
用法是我找到的一种变通方法。9avjhtql6#
我也有这个问题,我找到了一个变通办法,我的情况。
在这篇文章中,作者也有同样的问题
https://www.iphonelife.com/blog/31369/swift-programming-101-generics-practical-guide
所以问题似乎是,编译器需要以某种方式推断T的类型,但不允许简单地使用泛型(params ...)。< type >(params...).
通常情况下,编译器可以通过扫描参数类型来查找T的类型,因为在许多情况下,这是使用T的地方。
在我的例子中,有点不同,因为我的函数的返回类型是T,而在你的例子中,你似乎根本没有在函数中使用T,我猜你只是简化了示例代码。
所以我有以下函数
如果,比如说
编译器给出了错误:
无法显式专用化泛型函数
因此,为了给编译器提供另一个信息源来推断T的类型,必须显式声明保存返回值的变量的类型。
这样,编译器就知道T必须是整数。
所以我认为总的来说,它只是意味着,如果你指定了一个泛型函数,你至少要在参数类型中使用T,或者作为返回类型。
djp7away7#
雨燕5号
通常有很多方法来定义泛型函数,但是它们都基于
T
必须用作parameter
或return type
的条件。之后,我们必须在调用时提供
T
。参考:
yws3nbqq8#
解决方案是将类类型作为参数(类似于Java)
为了让编译器知道他正在处理什么类型,将类作为参数传递
呼叫身份: