2021年4月29日星期四

Swift: Same-Type requirement makes generic parameters equivalent?

I'm using swift 5 and try to compile the following code:

protocol BasicProtocol {      associatedtype T      var str: T {get set}  }    struct AItem<U>: BasicProtocol {      typealias T = U      var str: T            init<G: StringProtocol>(str: G) where G == T {          self.str = str      }  }  

I got compilation error:

error: Test.playground:10:45: error: same-type requirement makes generic parameters 'G' and 'U' equivalent      init<G: StringProtocol>(str: G) where G == T {                                              ^  

How to make them equivalent? or I can't?

Thanks.


Update 1:

This is the problem I encountered: I want to declare struct "AItem", hoping it has a generic type "T". And this generic type will have some restrictions, such as: "T: StringProtocol". Then for some reason, I need to use an array to load these structs, and ensure that the generics of each structure can be set at will.

I learned that there is "type-erase" might can solve this. So I tried this way, but it seemed unsuccessful. The problems mentioned above have occurred.


Update 2:

struct AItem<T: StringProtocol> {      var aStr: T  }    var array: [AItem<Any>] = [AItem(aStr: "asdfasdf")]  

Look,If you compile this code, you will get a compilation error:

error: Test.playground:5:13: error: type 'Any' does not conform to protocol 'StringProtocol'  var array: [AItem<Any>] = [AItem(aStr: "asdfasdf")]              ^    

If I use "var array: [AItem]", I will not be able to put any other non-"String" but implemented "StringProtocol" instance in the array.

This is why I said I want "ensure that the generics of each structure can be set at will".


Update 3:

very thanks for @jweightman, now I update my question again.

protocol ConstraintProtocol {}    extension String: ConstraintProtocol{}  extension Data: ConstraintProtocol{}  extension Int: ConstraintProtocol{}  .......    struct AItem<T = which class has Implemented "ConstraintProtocol"> {      var aPara: T      init(aPara:T) {          self.aPara = aPara      }  }  // make a array to contain them  var anArray: [AItem<Any class which Implemented "ConstraintProtocol">] = [AItem(aPara: "String"), AItem(aPara: 1234), AItem(aPara: Data("a path")), …]    // then I can use any item which in anArray. Maybe I will implement a method to judge these generics and perform the appropriate action.  for curItem in anArray {      var result = handleItem(curItem)      do something...  }      func handleItem<T: ConstraintProtocol>(item: AItem<T>) -> Any? {        if (item.T is ...) {          do someThing          return ......      } else if (item.T is ...) {          do someThing          return ...      }      return nil  }  

This is my whole idea, but all of which are pseudo-code.

https://stackoverflow.com/questions/67310832/swift-same-type-requirement-makes-generic-parameters-equivalent April 29, 2021 at 11:55AM

没有评论:

发表评论