【问题标题】:how to create values of type T in a generic如何在泛型中创建 T 类型的值
【发布时间】:2020-09-22 12:22:44
【问题描述】:

此 Swift 5 代码将通过将 dbl 的返回类型与接收返回值的变量的类型相匹配来选择调用哪个版本的 dbl

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 表示具有显式 init 的类或结构的特殊情况。但是泛型也应该适用于内置类型(IIUC)

【问题讨论】:

    标签: generics swift5


    【解决方案1】:

    您只需要约束您的泛型类型以符合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 但它可能返回 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-15
      相关资源
      最近更新 更多