错误消息非常清楚地说明了您需要在此处做什么 - 告诉编译器 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
我知道,这是一团糟。所以如果你要为各种Ts做这个,你可以先为长函数名做一个类型别名:
typealias XCTAssertEqualsType<T> = (@autoclosure () throws -> T, @autoclosure () throws -> T, T, @autoclosure () -> String, StaticString, UInt) -> ()
然后您可以使用XCTAssertEqualsType<Double> 和XCTAssertEqualsType<Float> 等。
但老实说,我不明白你为什么要给这个断言函数起别名。作为一个函数,你失去了很多它的特性。如果您通过变量调用它,则必须手动传入文件名和行号“魔术”参数。你失去了所有可选参数,正如我一开始所说,你失去了泛型。
如果你想要的只是函数的不同名称,也许你自己声明另一个函数:
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)
}