可以给可选的泛型参数设置默认值吗?
我正在尝试做这样一件事:
func addChannel<T>(name: String, data: T? = nil) -> Channel {
}
let myChannel = addChannel("myChannelName")
但是我收到了一个错误,提示:
无法推断泛型参数'T'
这是否意味着我所尝试的操作是不可能完成的?
按照你现在的方式是不可能做到的。仅凭上面的代码,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")
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>
我遇到了同样的问题。虽然传统上不能使用通用默认值(完全忽略参数),但我更喜欢下面的方法而不是实现重载:
let myChannel=addChannel("myChannelName", data: Optional<Any>.none)
我结合现有答案的方法,既可以在没有可选参数的情况下调用函数,又可以避免重复实现该函数。
func addChannel(name: String) -> Channel {
addChannel(name: name, data: Optional<Any>.nil)
}
func addChannel<T>(name: String, data: T? = nil) -> Channel {
...
}
如上所述,您应避免使用 Any
。在我的情况下,我知道 T
是一个 Encodable
,因此我使用以下代码:
struct DefaultEncodable: Encodable {}
func function1(name: String) {
addChannel(name: name, data: Optional<DefaultEncodable>.nil)
}
func function1<T: Encodable>(name: String, data: T? = nil) {
...
}
我在定义一个有大量泛型的复杂函数时遇到了类似的问题,如果使用重载将会导致无法管理的变化。以下是代码:
struct Channel{
//Your code here
}
class ChannelManager{
static let typedNil : Int? = nil //<--- This is what eliminates the error "Argument for generic parameter 'T' could not be inferred"
public static func addChannel<T>(name: String, data: T? = typedNil) -> Channel{
//Your code here
return Channel() //To demonstrate that code compiles
}
}
typedNil
并将其用作默认参数,预期的默认值仍然是nil
,但编译器将其视为nil
int
,因此能够推断出类型,避免了添加附加协议符合现有类型或要求重载的要求。请注意,将typedNil
声明为static
,否则编译将失败,并显示错误“无法使用实例成员'typedNil'作为默认参数”。
data
可以是任何类型的字典、整数或字符串,或者它可以为 nil。这样做的首选方式是将data: AnyObject? = nil
,然后在函数内部执行数据类型检查吗? - hamchapman