默认参数为通用类型 [英] Default parameter as generic type

查看:70
本文介绍了默认参数为通用类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有用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:


类型'A'的默认参数值不能转换为类型'T'。

Default argument value of type 'A' cannot be converted to type 'T'.

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

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

返回值:


默认参数值类型'P'不能转换为类型'T'

Default argument value of type 'P' cannot be converted to type 'T'

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

返回值:


'A'不能转换为'T';您是要使用 as!来强制向下转换吗?

'A' is not convertible to 'T'; did you mean to use 'as!' to force downcast?

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

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 中包含一个简单的初始化程序的蓝图,从而可以将泛型类型的实例初始化为默认参数;参见 @Sulthan:s的答案

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.

这篇关于默认参数为通用类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆