编译器在编译泛型函数时,会根据实参类型,以泛型函数为模板,合成对应的函数。
如果泛型函数有重载版本,编译器会以最接近实参类型的泛型函数为模板,进行函数合成。
eg1:
func test_func<T>(_ s: T) {
print(type(of: s), s)
}
func doTest() {
let a: Int = 1
let b: Int? = 2
let c: Int? = nil
test_func(a)
test_func(b)
test_func(c)
}
合成的函数是:
func test_func(_ s: Int) {
// let a: Int = 1 执行这个函数
print(type(of: s), s)
}
func test_func(_ s: Optional<Int>) {
// let b: Int? = 2 和 let c: Int? = nil 执行这个函数
print(type(of: s), s)
}
执行结果是:
let a: Int = 1 Int 1
let b: Int? = 2 Optional<Int> Optional(2)
let c: Int? = nil Optional<Int> nil
eg2:
func test_func<T>(_ s: T?) {
print(type(of: s), s, terminator: "")
if s != nil {
print(type(of: s!), s!)
} else {
print("error")
}
}
func doTest() {
let a: Int = 1
let b: Int? = 2
let c: Int? = nil
test_func(a)
test_func(b)
test_func(c)
}
合成的函数是:
func test_func(_ s: Int?) {
print(type(of: s), s, terminator: "")
if s != nil {
print(type(of: s!), s!)
} else {
print("error")
}
}
执行结果是:
let a: Int = 1 Optional<Int> Optional(1) Int 1
let b: Int? = 2 Optional<Int> Optional(2) Int 2
let c: Int? = nil Optional<Int> nil error
eg3:
func test_func<T>(_ s: T) {
print(type(of: s), s)
}
func test_func<T>(_ s: T?) {
print(type(of: s), s, terminator: "")
if s != nil {
print(type(of: s!), s!)
} else {
print("error")
}
}
func doTest() {
let a: Int = 1
let b: Int? = 2
let c: Int? = nil
test_func(a)
test_func(b)
test_func(c)
}
合成的函数是:
func test_func(_ s: Int) {
// let a: Int = 1 执行这个函数
print(type(of: s), s)
}
func test_func(_ s: Int?) {
// let b: Int? = 2 和 let c: Int? = nil 执行这个函数
print(type(of: s), s, terminator: "")
if s != nil {
print(type(of: s!), s!)
} else {
print("error")
}
}
执行结果是:
let a: Int = 1 Int 1
let b: Int? = 2 Optional<Int> Optional(2) Int 2
let c: Int? = nil Optional<Int> nil error
应用
自定义LSPrint
函数,能够准确判断参数items
的类型,并且获取到其值。
#if DEBUG
public func LSPrint(file: String = #file, line: UInt = #line, function: String = #function) {
print("\t" + (file as NSString).lastPathComponent + " [\(line)] " + function)
}
public func LSPrint<T>(_ items: @autoclosure () -> T, file: String = #file, line: UInt = #line, function: String = #function) {
let result = items()
print("\t" + (file as NSString).lastPathComponent + " [\(line)] " + function + " 输出: \(type(of: result))\n\(result)")
}
public func LSPrint<T>(_ items: @autoclosure () -> T?, file: String = #file, line: UInt = #line, function: String = #function) {
let result = items()
if result != nil {
print("\t" + (file as NSString).lastPathComponent + " [\(line)] " + function + " 输出: \(type(of: result))\n\(result!)")
} else {
print("\t" + (file as NSString).lastPathComponent + " [\(line)] " + function + " 输出: \(type(of: result)) = nil")
}
}
#else
public func LSPrint(_ items: @autoclosure () -> Any? = nil) {}
#endif