【问题标题】:How to cast generic T to conform to protocol如何强制转换泛型 T 以符合协议
【发布时间】:2016-04-27 14:45:39
【问题描述】:

我需要在类中转换泛型类型以符合协议。我不能使用约束,因为容器类必须被序列化。那么在这种情况下,当我已经知道(我可以检查你所看到的)它符合协议时,我怎么能将 T 转换为 ZNumeric?

//: Playground - noun: a place where people can play

import UIKit

protocol ZNumeric {

}

extension Double: ZNumeric {

}

class GenericClass<T> {

}

class RestrictedGenericClass<T:ZNumeric> {

}

class Container {
    required init?<T>(type: T.Type) {
        let a = GenericClass<T>()
        print(a)

        if T.self is ZNumeric.Type {
            print("is numeric")
            //let b = RestrictedGenericClass<T>() // Will not work obviously
            //print(b)
        }
    }
}

let cDouble = Container(type: Double.self) // if T.self is ZNumeric.Type is true
let cString = Container(type: String.self) // if T.self is ZNumeric.Type is false

【问题讨论】:

    标签: swift generics


    【解决方案1】:

    因为必须在编译时知道泛型,所以不能只在运行时检查一致性(我很确定)。我认为这更像你想要的:

    class Container {
        required init?<T>(type: T.Type) {
            let a = GenericClass<T>()
            print(a)
        }
    
        required init?<T : ZNumeric>(type: T.Type) {
            let a = GenericClass<T>()
            print(a)
    
            print("is numeric")
            let b = RestrictedGenericClass<T>()
            print(b)
        }
    }
    

    将在编译时选择更具体的初始化程序。

    【讨论】:

    【解决方案2】:

    我想你在找这个。

    protocol ZNumeric {
    
    }
    
    extension Double: ZNumeric {
    
    }
    
    class GenericClass<T> {
    
    }
    
    class RestrictedGenericClass<T:ZNumeric> {
    
    }
    
    class Container<T> {
        required init?(value: T) {
        }
        convenience init?(_ value: T) {
            self.init(value: value)
            let a = GenericClass<T>()
            print(a)
        }
    }
    extension Container where T: ZNumeric {
        convenience init?(_ value: T) {
            self.init(value: value)
            let b = RestrictedGenericClass<T>() // Will not work obviously
            print(b)
        }
    }
    
    print("test Double")
    let cDouble = Container(1.1) // if T.self is ZNumeric.Type is true
    print("test String")
    let cString = Container("") // if T.self is ZNumeric.Type is false
    
    // test Double
    // RestrictedGenericClass<Swift.Double>
    // test String
    // GenericClass<Swift.String>
    
    1. 制作内部必需的初始化程序
    2. 为 T: AnyObject 制作初始化器
    3. 为 T: ZNumeric 制作初始化程序

    【讨论】:

      猜你喜欢
      • 2020-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多