问题描述
我有用Swift编写的协议及其实现:
I have protocol and his implementation written in Swift:
protocol P {
}
struct A: P {
}
协议在某些情况下被用作通用类型函数:
Protocol is used as generic type for some function:
func foo<T: P>(param: T) {
}
func foo() {
foo(param: A())
}
直到现在一切正常。但我想将A()设置为给定函数的默认参数:
Until now everything works properly. But I would like to set A() as a default parameter of given function:
func foo<T: P>(param: T = A()) {
}
不幸的是,出现以下错误:
Unfortunately with following error:
或
func foo<T: P>(param: T = A() as P) {
}
,
let a: P = A()
func foo<T: P>(param: T = a) {
}
返回值:
或
func foo<T: P>(param: T = A() as T) {
}
返回值:
我做错了什么?问题出在哪里?
What I'm doing wrong? Where is the problem?
我不想使用这样的强制施放:
I do not want to use force cast like this:
func foo<T: P>(param: T = A() as! T) {
}
谢谢。
推荐答案
您正在尝试强制执行非通用默认值通用函数中的参数:您可能应该考虑要在此处实现的目标。
You're trying to enforce a non-generic default argument in a generic function: you should probably think over what you're trying to achieve here.
为了便于讨论,您可以包括尝试转换的 A()
转换为 T
,但是您需要将参数类型更改为可选,以允许转换失败( nil
),例如
For the sake of the discussion, you could include an attempted cast of A()
to T
in your function signature, but you'd need to change the argument type to optional to allow failed conversion (nil
), e.g.
func foo<T: P>(param: T? = (A() as? T)) { }
一个更合理的选择是-除了泛型函数外,还包括针对以下情况的具体非泛型函数: T
是 A
(具体函数将优先于泛型函数),在这种情况下,您可以包括默认参数具体函数的函数签名中的 A()
。例如,
A more sound alternative is including - in addition to your generic function - a concrete non-generic function for instances where T
is A
(concrete functions will take precedence over generic ones), in which case you can include the default argument of A()
in the function signature of the concrete function. 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
):这里没有冲突,因为具体函数优先。
Note that the non-generic foo
is called even though A
conforms to P
(A
could've made use of the generic foo
): there's no conflict here as the concrete function takes precedence.
另一方面,如果您只是想让您的泛型函数允许不使用单个参数的调用(即,使用默认参数),您可以在 P
中包含一个简单的初始化程序的蓝图,从而可以将泛型类型的实例初始化为默认参数;参见。
If you, on the other hand, just want your generic function to allow calling without the single argument (i.e., making use of a default argument), you can include a blueprint of a simple initializer in P
, allowing you to initialize an instance of the generic type as default argument; see @Sulthan:s answer.
这篇关于默认参数为通用类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!