2015-11-19 49 views
1

我需要在類中強制泛型以符合協議。因爲容器類必須被序列化,所以我不能使用約束。那麼我怎麼能在這種情況下將T轉換爲ZNumeric,當我已經知道(我可以檢查,因爲你看到),它符合協議?如何投射泛型T以符合協議

//: 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 

回答

2

因爲在編譯時必須知道泛型,所以不能只在運行時檢查一致性(我很確定)。我認爲這更像你想要的:

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) 
    } 
} 

在編譯時將選擇更具體的初始化程序。

+0

啊,好,但在現實情況下,它是一個子類,然後整個想法打破:(這驅使我堅果http://stackoverflow.com/questions/33810702/possible-bug-i-can-create-generic-instance-ignoring-constraint – Alex

0

我想你在找這個。

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. 使對於T內部所需的初始化程序
  2. 化妝初始化:AnyObject
  3. 化妝初始化爲T:ZNumeric