如何在泛型中创建 T 类型的值

how to create values of type T in a generic

此 Swift 5 代码将通过将 dbl 的 return 类型与接收 return 值:

func dbl(_ x: Int) -> Int {
    print("called Intdbl")
    return Int(x * 2)
}

func dbl(_ x: Int) -> Float {
    print("called Floatdbl")
    return Float(x * 2)
}

var intsum : Int = 0 
var floatsum : Float = 0 

intsum = dbl(2) // prints "called Intdbl" and assigns Int(4)
floatsum = dbl(2) // prints "called Floatdbl" and assigns Float(4)

如果我想将其转换为通用函数怎么办?我想它应该是这样的:

func dbl<T>(_ x: Int) -> T {
    return T(x * 2)
}

var intsum : Int = 0
var floatsum : Float = 0

intsum = dbl(2)
floatsum = dbl(2)

但这失败并出现错误: Non-nominal type 'T' does not support explicit initialization.

还有这个:

func dbl<T>(_ x: Int) -> T {
    return T.init(x * 2)
}

var intsum : Int = 0
var floatsum : Float = 0

intsum = dbl(2)
floatsum = dbl(2)

失败并出现错误 Type 'T' has no member 'init'

一般来说,如果不是 TT.init,您如何使用泛型类型(如 T)创建新值?

FWIW 我假设这在 T 表示 class 或具有显式 init 的结构的特殊情况下有效。但是泛型也应该与内置类型一起工作 (IIUC)

您只需要约束您的通用类型以符合 Numeric 协议。顺便说一句,你不需要初始化一个新类型:

func dbl<T: Numeric>(_ x: T) -> T { x * 2 }

let intDbl: Int  = dbl(2)         // 4
let floatDbl: Float = dbl(2)      // 4.0
let floatDbl2: Float = dbl(2.75)  // 5.5

如果您只想将参数保留为整数,您可以使用 Numeric 完全容易出错的初始值设定项,它采用 BinaryInteger 但它可能 return nil:

init?<T>(exactly source: T) where T : BinaryInteger

func dbl<T: Numeric, U: BinaryInteger>(_ x: U) -> T? {
    guard let value = T(exactly: x) else { return nil }
    return value * 2
}

let intDbl: Int?  = dbl(2)     // 4
let floatDbl: Float? = dbl(2)  // 4.0