我有用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) {
}
提前谢谢。
答案 0 :(得分:4)
您试图在通用函数中强制执行非泛型默认参数:您应该考虑一下您在此处尝试实现的内容。
为了便于讨论,您可以在您的功能签名中包含A()
到T
的强制转换,但您需要更改参数类型为可选,以允许转换失败(nil
),例如
func foo<T: P>(param: T? = (A() as? T)) { }
除了通用函数之外,更合理的替代方案还包括T
为A
的实例的具体非泛型函数(具体函数优先于通用函数),其中例如,您可以在具体函数的函数签名中包含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
符合A
(P
通用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>
但是,你会遇到另一个问题。传递参数的类型决定了泛型的类型,因此您必须以其他方式指定泛型类型。