【问题标题】:Default parameter as generic type默认参数作为泛型类型
【发布时间】:2016-11-14 14:01:07
【问题描述】:

我有协议和他用 Swift 编写的实现:

protocol P {
}

struct A: P {
}

Protocol 被用作某些函数的泛型:

func foo<T: P>(param: T) {
}

func foo() {
    foo(param: A())
}

到目前为止,一切正常。但我想将 A() 设置为给定函数的默认参数:

func foo<T: P>(param: T = A()) {
}

很遗憾出现以下错误:

“A”类型的默认参数值无法转换为“T”类型。

或者

func foo<T: P>(param: T = A() as P) {
}

,

let a: P = A()
func foo<T: P>(param: T = a) {
}

返回:

“P”类型的默认参数值无法转换为“T”类型

或者

func foo<T: P>(param: T = A() as T) {
}

返回:

'A' 不能转换为 'T';你的意思是用'as!'强制沮丧?

我做错了什么?问题出在哪里?

我不想像这样使用强制转换:

func foo<T: P>(param: T = A() as! T) {
}

提前谢谢你。

【问题讨论】:

    标签: swift generics default


    【解决方案1】:

    您正在尝试在泛型函数中强制使用非泛型默认参数:您可能应该考虑一下您要在此处实现的目标。

    为了便于讨论,您可以在您的函数签名中尝试将A() 转换为T,但您需要将参数类型更改为可选以允许转换失败 (nil),例如

    func foo<T: P>(param: T? = (A() as? T)) { }
    

    一个更合理的选择是包括 - 除了你的泛型函数 - 一个具体的非泛型函数 TA 的实例(具体函数将优先于泛型函数),在这种情况下你可以包括A() 在具体函数的函数签名中的默认参数。例如

    protocol P { }
    struct A: P { }
    extension Int: P { }
    
    func foo<T: P>(param: T) { print("called generic foo") }
    func foo(param: A = A()) { print("called A specific foo") }
    
    foo()    // called A specific foo (making use of default arg)
    foo(A()) // called A specific foo
    foo(1)   // called generic foo
    

    请注意,即使 A 符合 PA 可以使用通用 foo),也会调用非泛型 foo:没有这里有冲突,因为具体函数优先。


    另一方面,如果您只是希望您的通用函数允许在没有单个参数的情况下调用(即,使用默认参数),您可以在 P 中包含一个简单初始化程序的蓝图,允许您将泛型类型的实例初始化为默认参数;见@Sulthan:s answer

    【讨论】:

      【解决方案2】:

      您唯一需要做的就是在协议中添加对初始化程序的要求:

      protocol P {
          init()
      }
      
      struct A: P {
          var x: Int
      
          init() {
              x = 10
          }
      }
      
      func foo<T: P>(param param: T = T()) {
      }
      

      但是,您将遇到另一个问题。传递参数的类型决定了泛型的类型,因此您必须以其他方式指定泛型类型。

      【讨论】:

        猜你喜欢
        • 2016-10-11
        • 2018-02-18
        • 2011-06-15
        • 1970-01-01
        • 2017-12-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多