如何在 Swift 中重新分配一个接受泛型类型参数的函数?
How do I reassign a function which takes a generic type argument in Swift?
披露,这是我写任何 Swift 的第一天,我来自 JS/TS 背景。
我习惯于简单地重新分配函数,如下所示:
let assertEqual = XCTAssertEqual
XCTAssertEqual 具有以下声明:
func XCTAssertEqual<T>(_ expression1: @autoclosure () throws -> T, _ expression2: @autoclosure () throws -> T, accuracy: T, _ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) where T : FloatingPoint
swift 操场抛出以下错误:
Generic parameter 'T' could not be inferred
我意识到这个赋值并不是特别的"valuable",但我可能想在将来为其他具有泛型类型参数的函数起别名,并且想了解更多关于任何Swift-具体约定。
错误消息非常清楚您需要在此处做什么 - 告诉编译器 T
应该是什么类型。不幸的是,您不能拥有未绑定 T
.
的 "generic variable"
为此,您需要写出函数 XCTAssertEquals<T>
的 完整类型名称 ,对于 T == Double
,它是:
(@autoclosure () throws -> Double, @autoclosure () throws -> Double, Double, @autoclosure () -> String, StaticString, UInt) -> ()
所以你需要:
let assertEqual: (@autoclosure () throws -> Double, @autoclosure () throws -> Double, Double, @autoclosure () -> String, StaticString, UInt) -> () = XCTAssertEqual
我知道,这是一团糟。所以如果你要为各种T
做这个,你可以先为长函数名做一个类型别名:
typealias XCTAssertEqualsType<T> = (@autoclosure () throws -> T, @autoclosure () throws -> T, T, @autoclosure () -> String, StaticString, UInt) -> ()
然后你可以使用XCTAssertEqualsType<Double>
和XCTAssertEqualsType<Float>
等
但老实说,我不明白你为什么要为这个断言函数起别名。作为一个函数,你失去了它的很多特性。如果您通过变量调用它,则必须手动传递文件名和行号 "magic" 参数。你失去了所有的可选参数,正如我在开始时所说的,你失去了泛型。
如果您想要的只是函数的不同名称,也许只需自己声明另一个函数:
func anotherName<T>(_ expression1: @autoclosure () throws -> T, _ expression2: @autoclosure () throws -> T, accuracy: T, _ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) where T : FloatingPoint {
XCTAssertEqual(try expression1(), try expression2(), accuracy: accuracy, message(), file: file, line: line)
}
披露,这是我写任何 Swift 的第一天,我来自 JS/TS 背景。
我习惯于简单地重新分配函数,如下所示:
let assertEqual = XCTAssertEqual
XCTAssertEqual 具有以下声明:
func XCTAssertEqual<T>(_ expression1: @autoclosure () throws -> T, _ expression2: @autoclosure () throws -> T, accuracy: T, _ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) where T : FloatingPoint
swift 操场抛出以下错误:
Generic parameter 'T' could not be inferred
我意识到这个赋值并不是特别的"valuable",但我可能想在将来为其他具有泛型类型参数的函数起别名,并且想了解更多关于任何Swift-具体约定。
错误消息非常清楚您需要在此处做什么 - 告诉编译器 T
应该是什么类型。不幸的是,您不能拥有未绑定 T
.
为此,您需要写出函数 XCTAssertEquals<T>
的 完整类型名称 ,对于 T == Double
,它是:
(@autoclosure () throws -> Double, @autoclosure () throws -> Double, Double, @autoclosure () -> String, StaticString, UInt) -> ()
所以你需要:
let assertEqual: (@autoclosure () throws -> Double, @autoclosure () throws -> Double, Double, @autoclosure () -> String, StaticString, UInt) -> () = XCTAssertEqual
我知道,这是一团糟。所以如果你要为各种T
做这个,你可以先为长函数名做一个类型别名:
typealias XCTAssertEqualsType<T> = (@autoclosure () throws -> T, @autoclosure () throws -> T, T, @autoclosure () -> String, StaticString, UInt) -> ()
然后你可以使用XCTAssertEqualsType<Double>
和XCTAssertEqualsType<Float>
等
但老实说,我不明白你为什么要为这个断言函数起别名。作为一个函数,你失去了它的很多特性。如果您通过变量调用它,则必须手动传递文件名和行号 "magic" 参数。你失去了所有的可选参数,正如我在开始时所说的,你失去了泛型。
如果您想要的只是函数的不同名称,也许只需自己声明另一个函数:
func anotherName<T>(_ expression1: @autoclosure () throws -> T, _ expression2: @autoclosure () throws -> T, accuracy: T, _ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) where T : FloatingPoint {
XCTAssertEqual(try expression1(), try expression2(), accuracy: accuracy, message(), file: file, line: line)
}