小编典典

Swift函数中可选通用参数的默认值

swift

是否可以为可选的通用参数提供默认值?

我正在尝试做这样的事情:

func addChannel<T>(name: String, data: T? = nil) -> Channel {

}

let myChannel = addChannel("myChannelName")

但我说错了

Argument for generic parameter 'T' could not be inferred

这只是我试图做的不可能的事吗?


阅读 796

收藏
2020-07-07

共1个答案

小编典典

用您完成的方式是不可能的。仅考虑上述代码,什么是类型T?就像它说的那样,编译器无法弄清楚(我也不能,因为数据不存在,我也不能。)

特定问题的解决方案是重载而不是使用默认值:

func addChannel<T>(name: String, data: T?) -> Channel { ... }

func addChannel(name: String) -> Channel { ... }

let myChannel = addChannel("myChannelName")

但这引发了您在这里做什么的问题。您会认为Channel应该如此Channel<T>。否则,您在做什么data?如果不诉诸Any(您应该强烈避免),那么很难看到您的函数除了忽略之外还能做什么data

有了Channel<T>你可以只使用一个默认的,但你必须提供类型:

func addChannel<T>(name: String, data: T? = nil) -> Channel<T> { ... }
let myChannel: Channel<Int> = addChannel("myChannelName")

否则,编译器将不知道您正在建立哪种通道。

(更新〜Swift 5.2)

有时,您需要使用的默认类型T。您可以重载。例如,您可能希望默认类型为Never。在这种情况下,您将添加如下重载:

func addChannel<T>(name: String, data: T? = nil) -> Channel<T> { ... }
func addChannel(name: String) -> Channel<Never> { 
    addChannel(name: name, data: Optional<Never>.none)
}

这样,您可以进行更简单的调用:

let myChannel = addChannel(name: "myChannelName") // Channel<Never>
2020-07-07