在泛型中使用类型变量 [英] Using a Type Variable in a Generic

查看:228
本文介绍了在泛型中使用类型变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个问题,除了Swift。如何在泛型中使用 Type 变量?



我试过这个:

  func intType() - > Int.Type {
return Int.self
}

func test(){
var t = self.intType()
var arr = Array< ; t>()//错误:'t'不是类型。呃...是的,是的。
}

这也行不通:

  var arr = Array< t.Type>()//错误:'t'不是类型
var arr = Array< t。 self>()// Swift似乎根本不懂这个语法。

有没有办法做到这一点?我感觉Swift只是不支持它,并给我一些模棱两可的错误消息。



编辑:这是一个更复杂的示例问题无法使用通用函数头来绕过。当然它没有任何意义,但是我在代码中的某处使用了这种功能,并且希望发布一个干净的例子来代替我的实际代码:

  func someTypes() - > (任何类型){
var ret = [Any.Type]()
for(var i = 0; i< rand()%10; i ++){
if(rand )%2 == 0){ret.append(Int.self)}
else {ret.append(String.self)}
}
return ret
}

func test(){
var ts = self.someTypes()

for $ {
var arr = Array< t>()



解决方案

静态类型意味着一种类型的a在一个通用函数 func foo< T>(){...} 的上下文中, code>, T 看起来像一个变量,但是它的类型实际上是在编译时根据函数从调用的位置已知的。 Array< T>()的行为取决于 T ,但是这个信息在编译时已知。



使用协议时,Swift使用动态分派,因此您可以编写 Array< MyProtocol> (),并且数组只存储对实现 MyProtocol 的引用 - 所以当你从数组中获取某些东西时,你可以访问所有 MyProtocol



但是如果 t 实际上是一个变量类型 Any.Type 数组< t>()没有意义,因为它的类型实际上在编译时不知道。 (由于 Array 是一个通用结构,因此编译器需要知道哪种类型可用作泛型参数,但这是不可能的。)



我建议您今年从WWDC观看一些视频: b
$ b



我发现这张幻灯片特别有助于理解协议和动态分派:


I have this question except for Swift. How do I use a Type variable in a generic?

I tried this:

func intType() -> Int.Type {
    return Int.self
}

func test() {
    var t = self.intType()
    var arr = Array<t>() // Error: "'t' is not a type". Uh... yeah, it is.
}

This didn't work either:

var arr = Array<t.Type>() // Error: "'t' is not a type"
var arr = Array<t.self>() // Swift doesn't seem to even understand this syntax at all.

Is there a way to do this? I get the feeling that Swift just doesn't support it and is giving me somewhat ambiguous error messages.

Edit: Here's a more complex example where the problem can't be circumvented using a generic function header. Of course it doesn't make sense, but I have a sensible use for this kind of functionality somewhere in my code and would rather post a clean example instead of my actual code:

func someTypes() -> [Any.Type] {
    var ret = [Any.Type]()
    for (var i = 0; i<rand()%10; i++) {
        if (rand()%2 == 0){ ret.append(Int.self) }
        else {ret.append(String.self) }
    }
    return ret
}

func test() {
    var ts = self.someTypes()

    for t in ts {
        var arr = Array<t>()
    }
}

解决方案

Swift's static typing means the type of a variable must be known at compile time.

In the context of a generic function func foo<T>() { ... }, T looks like a variable, but its type is actually known at compile time based on where the function is called from. The behavior of Array<T>() depends on T, but this information is known at compile time.

When using protocols, Swift employs dynamic dispatch, so you can write Array<MyProtocol>(), and the array simply stores references to things which implement MyProtocol — so when you get something out of the array, you have access to all functions/variables/typealiases required by MyProtocol.

But if t is actually a variable of kind Any.Type, Array<t>() is meaningless since its type is actually not known at compile time. (Since Array is a generic struct, the compiler needs know which type to use as the generic parameter, but this is not possible.)

I would recommend watching some videos from WWDC this year:

I found this slide particularly helpful for understanding protocols and dynamic dispatch:

这篇关于在泛型中使用类型变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆