将默认值或 nil 值设置为函数的泛型类型参数
Set default or nil value to the generic type parameter of the function
假设我有一个协议
protocol TestProtocol {
}
此外,拥有一个结构并从协议继承它。
struct StructOne: TestProtocol {
}
现在,我有一个视图控制器 class 并创建了一个通用函数来接受一组 TestProtocol
类型的对象(这是一个通用参数)。这是用于 SDK API 调用的传递参数。
但是在某些API调用中,我不需要传递这个参数数组。所以,我只想在函数定义中设置 nil 值或默认空数组。
这是class
class TestViewController: UIViewController {
// func genericCall<T: TestProtocol>(param: [T] = []) { // Not work
// func genericCall<T: TestProtocol>(param: [T]? = nil) { // Not work
func genericCall<T: TestProtocol>(param: [T]?) {
if param?.isEmpty == true {
print("Empty Param Calling")
} else {
print("With Param Calling")
}
}
override func viewDidLoad() {
super.viewDidLoad()
let param = [StructOne(), StructOne()]
self.genericCall(param: param) // This one work
self.genericCall(param: [] as [StructOne]) // This one also work. But want default value in function
self.genericCall(param: nil) // Not work : Error - Generic parameter 'T' could not be inferred
// self.genericCall() // Not work with default empty value : Error - Generic parameter 'T' could not be inferred
}
}
我收到此编译时错误:无法推断通用参数 'T'
我可以在函数调用期间设置一个空数组。这是提及
我也检查了这个,如果只有T类型,它允许设置nil值,但这里是T([T])的数组。
有没有什么方法可以设置默认的 nil 值或任何其他方法可以将默认值设置为空数组?这样我们就可以避免将空数组传递给每个函数调用。
更新:
我不能这样用。由于SDK函数调用不允许我传递参数值。
func genericCall(param: [TestProtocol] = []) {
// param: Not allowed me to pass to the sdk call function.
if param.isEmpty == true {
print("Empty Param Calling")
} else {
print("With Param Calling")
}
}
注意:这是一个演示代码。实际上,我使用的是其中一个 SDK,因此我无法在协议中进行更多更改。
nil
在这种情况下太宽泛了,因为编译器无法推断出它应该将 nil 应用到哪个 [T]?
。
您需要在此处明确指定 Optional
通用参数:
self.genericCall(param: [StructOne]?.none)
您可以创建一个通用方法,将您的通用类型限制为 RangeReplaceableCollection
,并将其 Element
限制为您的 TestProtocol
。它起作用的原因是 RangeReplaceableCollection
要求符合它的协议提供一个空的初始值设定项:
protocol TestProtocol { }
struct StructOne: TestProtocol { }
class TestViewController: UIViewController {
func genericCall<T: RangeReplaceableCollection>(param: T = .init()) -> T where T.Element: TestProtocol {
if param.isEmpty {
print("Empty Param Calling")
} else {
print("With Param Calling")
}
return param
}
override func viewDidLoad() {
super.viewDidLoad()
let result: [StructOne] = genericCall() // This one work
print(result)
}
}
假设我有一个协议
protocol TestProtocol {
}
此外,拥有一个结构并从协议继承它。
struct StructOne: TestProtocol {
}
现在,我有一个视图控制器 class 并创建了一个通用函数来接受一组 TestProtocol
类型的对象(这是一个通用参数)。这是用于 SDK API 调用的传递参数。
但是在某些API调用中,我不需要传递这个参数数组。所以,我只想在函数定义中设置 nil 值或默认空数组。
这是class
class TestViewController: UIViewController {
// func genericCall<T: TestProtocol>(param: [T] = []) { // Not work
// func genericCall<T: TestProtocol>(param: [T]? = nil) { // Not work
func genericCall<T: TestProtocol>(param: [T]?) {
if param?.isEmpty == true {
print("Empty Param Calling")
} else {
print("With Param Calling")
}
}
override func viewDidLoad() {
super.viewDidLoad()
let param = [StructOne(), StructOne()]
self.genericCall(param: param) // This one work
self.genericCall(param: [] as [StructOne]) // This one also work. But want default value in function
self.genericCall(param: nil) // Not work : Error - Generic parameter 'T' could not be inferred
// self.genericCall() // Not work with default empty value : Error - Generic parameter 'T' could not be inferred
}
}
我收到此编译时错误:无法推断通用参数 'T'
我可以在函数调用期间设置一个空数组。这是提及
我也检查了这个
有没有什么方法可以设置默认的 nil 值或任何其他方法可以将默认值设置为空数组?这样我们就可以避免将空数组传递给每个函数调用。
更新:
我不能这样用。由于SDK函数调用不允许我传递参数值。
func genericCall(param: [TestProtocol] = []) {
// param: Not allowed me to pass to the sdk call function.
if param.isEmpty == true {
print("Empty Param Calling")
} else {
print("With Param Calling")
}
}
注意:这是一个演示代码。实际上,我使用的是其中一个 SDK,因此我无法在协议中进行更多更改。
nil
在这种情况下太宽泛了,因为编译器无法推断出它应该将 nil 应用到哪个 [T]?
。
您需要在此处明确指定 Optional
通用参数:
self.genericCall(param: [StructOne]?.none)
您可以创建一个通用方法,将您的通用类型限制为 RangeReplaceableCollection
,并将其 Element
限制为您的 TestProtocol
。它起作用的原因是 RangeReplaceableCollection
要求符合它的协议提供一个空的初始值设定项:
protocol TestProtocol { }
struct StructOne: TestProtocol { }
class TestViewController: UIViewController {
func genericCall<T: RangeReplaceableCollection>(param: T = .init()) -> T where T.Element: TestProtocol {
if param.isEmpty {
print("Empty Param Calling")
} else {
print("With Param Calling")
}
return param
}
override func viewDidLoad() {
super.viewDidLoad()
let result: [StructOne] = genericCall() // This one work
print(result)
}
}