默认参数为泛型类型

时间:2016-07-12 11:01:14

标签: swift generics default

我有用Swift编写的协议及其实现:

protocol P {
}

struct A: P {
}

协议用作某些功能的通用类型:

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) {
}

提前谢谢。

2 个答案:

答案 0 :(得分:4)

您试图在通用函数中强制执行非泛型默认参数:您应该考虑一下您在此处尝试实现的内容。

为了便于讨论,您可以在您的功能签名中包含A()T的强制转换,但您需要更改参数类型为可选,以允许转换失败(nil),例如

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

除了通用函数之外,更合理的替代方案还包括TA的实例的具体非泛型函数(具体函数优先于通用函数),其中例如,您可以在具体函数的函数签名中包含A()的默认参数。 E.g。

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

请注意,即使foo符合AP 通用A):这里没有冲突,因为具体的功能优先。

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

答案 1 :(得分:1)

您唯一需要的是为协议添加初始化程序的要求:

<logic:iterate name="listMsg" id="listMsgId">
<p>
    <%
        String firstName = "Get data from this list";
     %>
    List Messages <bean:write name="listMsgId"/>
</p>
</logic:iterate>

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