【问题标题】:Swift use generic function in generic classSwift 在泛型类中使用泛型函数
【发布时间】:2017-06-07 14:51:05
【问题描述】:

我正在使用 Generic 开发应用程序。

但是在泛型类中使用泛型函数存在问题。

如你所知,我们使用泛型:

class ClassA{
    static func myFunction<Type>()->Type where Type : Protocol1, Type : Protocol2{
        ...
        return Type
    }
}


class ClassB{
    func myFunction(){
        let a : ClassC = ClassA.myFunction()
    }
}

class ClassC : Protocol1, Protocol2{

}

而且,这很好用。

但我想做的是:

class ClassA{
    static func myFunction<Type>()->Type where Type : Protocol1, Type : Protocol2{
        ...
        return Type
    }
}


class ClassB<Type : Protocol1, Protocol2>{
    func myFunction(){
        let a : Type = ClassA.myFunction()
    }
}

这段代码给了我“无法推断通用参数'类型'”错误。

我试过了:

class ClassB<Type> where Type : Protocol1, Type : Protocol2{

但是没用……

是否可以使用泛型类型来推断其他泛型类型?

【问题讨论】:

  • 问题仅仅是你说的ClassB&lt;Type : Protocol1, Protocol2&gt;——它定义了两个通用占位符,TypeProtocol2。你想说ClassB&lt;Type : Protocol1 &amp; Protocol2&gt;,它定义了一个单个通用占位符Type,它同时符合Protocol1Protocol2

标签: swift generics swift3


【解决方案1】:

我会说你有点搞砸了类型推断。它是如何工作的:通常你有这样的东西:

var a = "Some string"

在这种情况下,a 的类型是通过赋值来推断的 - 已知它是 String,仅此而已。

更复杂的例子:

func returnString() -> String {
    return "Some string"
}
var b = returnString()

在这种情况下,类型从函数签名推断,从返回类型 - 它是String,并在其签名中声明:-&gt; String。编译器肯定知道,b 将是 String 类型。

使用泛型,类型推断变得有点复杂。让我们看看你的函数:

let a : Type = ClassA.myFunction()

我们在这里看到了什么? a 的类型未知,编译器应该从您正在调用的函数中推断类型。我们开工吧!看函数签名:

static func myFunction<Type>()->Type where Type : Protocol1, Type : Protocol2

作为编译器,我会感到困惑,因为函数的返回类型必须反过来从其他地方推断出来,在这种情况下,“某处”正是您定义并希望分配给的变量的类型(因为没有其他地方, 真的)。但是,您也没有指定变量的类型。这正是您收到“无法推断通用参数‘类型’”错误的原因 - 表达式的双方都有未知类型,必须相互推断

在这里工作:

let a : ClassC = ClassA.myFunction()

正是因为如此 - 您指定的不是抽象类型,而是具体类型 : ClassC,编译器知道,它必须将 func myFunction ... 中的 Type 替换为 ClassC

总而言之,我想说的是,对于像您这样的泛型函数,类型推断的工作方向完全不同——不是从被调用的函数推断变量的类型,而是从变量推断的函数类型。

【讨论】:

  • 感谢您的回答。我认为编译器可以在以后推断出更多类型。像(类->通用类->静态通用函数),但我想它不能。我真的很感谢你的帮助!
  • a 的类型未知”是什么意思?编译器知道它必须是Type 类型,因为这就是它的注释。
  • @Hamish 它可能不是最好的词选择,但我希望想法很清楚——无论是编译器,你也不能真正说出Type 的真正含义。它没有在某个地方实现,事实上,它只是一些具体类型的占位符。
  • @FyodorVolchyok 当然,它是一个类型的占位符,但myFunction 函数中的通用占位符也是如此——ClassB 的通用占位符可以满足这一要求。这里的实际问题是OP错误地定义了ClassB的通用占位符——see my above comment
  • @Hamish,嗯,是的,我完全错过了问题的重点,看来你是对的。写下你的评论作为答案,让我们等待OP
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-27
相关资源
最近更新 更多