Swift 个可选的方法参数,但至少需要填充一个
Swift optional method arguments but at least one needs to be populated
我正在为 swift 中的 class 创建一个带有 2 个参数的方法,它们都是可选的。但是,我至少需要填充其中一个才能使该方法成功运行,哪个都不重要
func someMethod(arg1: Sometype?, arg2: Sometype?)-> Void {
//I need at least one argument to
//be populated to do what i need
}
在 Objective-c 中,如果这两个对象都为 nil,我们可以抛出一个断言。在 Swift 我想知道是否有比断言更好的方法。
您可以改用重载:
// arg1 cannot be nil
func someMethod(arg1: Int, arg2: Int?)-> Void {
println("arg2 was nil")
somePrivateMethod(arg1,arg2)
}
// arg2 cannot be nil
func someMethod(arg1: Int?, arg2: Int)-> Void {
println("arg1 was nil")
somePrivateMethod(arg1,arg2)
}
// this version is needed to avoid annoying "ambiguous call"
// errors when passing two non-optionals in...
func someMethod(arg1: Int, arg2: Int)-> Void {
println("neither was nil")
somePrivateMethod(arg1,arg2)
}
private func somePrivateMethod(arg1: Int?, arg2: Int?)-> Void {
// private method in which at least arg1 or arg2 will be guaranteed non-nil
}
someMethod(1, nil) // prints "arg2 was nil"
someMethod(nil, 1) // prints "arg1 was nil"
someMethod(1, 1) // prints "neither was nil"
// but if you try this:
someMethod(nil, nil) // error: cannot find an overload for 'someMethod'
// that accepts an argument list of type '(nil, nil)'
这样做的缺点是调用者被迫展开参数——他们不能在不检查至少其中一个是非零的情况下传递两个可选值。但这是一个功能,而不是错误!因为这意味着调用者实际上不可能意外调用 API "the wrong way" 并生成断言。
当然,这确实会引出一个问题,即您是否真的想要采用不同数量的参数或不同类型的多个重载(请参阅 Rob 的回答),这在您的用例上下文中也值得考虑。
我同意 Airspeed Velocity 的观点,您应该在此处使用重载,但我会以不同的方式进行处理。完全摆脱选项。
func someMethod(#arg1: Sometype)-> Void {}
func someMethod(#arg2: Sometype)-> Void {}
func someMethod(#arg1: Sometype, #arg2: Sometype) -> Void {}
在这一点上,很明显这些是真正不同的方法:
func someMethodWithArg1(arg1: Sometype)-> Void {}
func someMethodWithArg2(arg2: Sometype)-> Void {}
func someMethod(#arg1: Sometype, #arg2: Sometype) -> Void {}
为了使这个具体化,请考虑我们是否正在制作一个 FixedLengthString
class,您可以将长度或现有字符串传递给它,或者您可以同时传递两者并重复字符串,直到它填满长度。
您所描述的是:
func makeString(length: Int?, string: String?) -> FixedString
但不仅如此,只需制作方法:
func makeStringWithLength(length: Int) -> FixedString
func makeStringFromString(string: String) -> FixedString
func makeStringByFillingWith(string: String, totalLength: Int) -> FixedString
这样就更清楚了一切是如何运作的,而且你不能错误地调用它。这也是您在 ObjC 中应该做的。
我正在为 swift 中的 class 创建一个带有 2 个参数的方法,它们都是可选的。但是,我至少需要填充其中一个才能使该方法成功运行,哪个都不重要
func someMethod(arg1: Sometype?, arg2: Sometype?)-> Void {
//I need at least one argument to
//be populated to do what i need
}
在 Objective-c 中,如果这两个对象都为 nil,我们可以抛出一个断言。在 Swift 我想知道是否有比断言更好的方法。
您可以改用重载:
// arg1 cannot be nil
func someMethod(arg1: Int, arg2: Int?)-> Void {
println("arg2 was nil")
somePrivateMethod(arg1,arg2)
}
// arg2 cannot be nil
func someMethod(arg1: Int?, arg2: Int)-> Void {
println("arg1 was nil")
somePrivateMethod(arg1,arg2)
}
// this version is needed to avoid annoying "ambiguous call"
// errors when passing two non-optionals in...
func someMethod(arg1: Int, arg2: Int)-> Void {
println("neither was nil")
somePrivateMethod(arg1,arg2)
}
private func somePrivateMethod(arg1: Int?, arg2: Int?)-> Void {
// private method in which at least arg1 or arg2 will be guaranteed non-nil
}
someMethod(1, nil) // prints "arg2 was nil"
someMethod(nil, 1) // prints "arg1 was nil"
someMethod(1, 1) // prints "neither was nil"
// but if you try this:
someMethod(nil, nil) // error: cannot find an overload for 'someMethod'
// that accepts an argument list of type '(nil, nil)'
这样做的缺点是调用者被迫展开参数——他们不能在不检查至少其中一个是非零的情况下传递两个可选值。但这是一个功能,而不是错误!因为这意味着调用者实际上不可能意外调用 API "the wrong way" 并生成断言。
当然,这确实会引出一个问题,即您是否真的想要采用不同数量的参数或不同类型的多个重载(请参阅 Rob 的回答),这在您的用例上下文中也值得考虑。
我同意 Airspeed Velocity 的观点,您应该在此处使用重载,但我会以不同的方式进行处理。完全摆脱选项。
func someMethod(#arg1: Sometype)-> Void {}
func someMethod(#arg2: Sometype)-> Void {}
func someMethod(#arg1: Sometype, #arg2: Sometype) -> Void {}
在这一点上,很明显这些是真正不同的方法:
func someMethodWithArg1(arg1: Sometype)-> Void {}
func someMethodWithArg2(arg2: Sometype)-> Void {}
func someMethod(#arg1: Sometype, #arg2: Sometype) -> Void {}
为了使这个具体化,请考虑我们是否正在制作一个 FixedLengthString
class,您可以将长度或现有字符串传递给它,或者您可以同时传递两者并重复字符串,直到它填满长度。
您所描述的是:
func makeString(length: Int?, string: String?) -> FixedString
但不仅如此,只需制作方法:
func makeStringWithLength(length: Int) -> FixedString
func makeStringFromString(string: String) -> FixedString
func makeStringByFillingWith(string: String, totalLength: Int) -> FixedString
这样就更清楚了一切是如何运作的,而且你不能错误地调用它。这也是您在 ObjC 中应该做的。