Conditional generic initializers?


(Neil Faiman) #1

Is it possible for a generic class to have methods (specifically, initializers) which are only defined if the generic parameters meet certain constratins?

Here’s a concrete example:

    class Foo <T1, T2> {
        init(pairs: [(T1, T2)]) {}
        // What I’d like to be able to doL
        convenience init "where T1 == T2" (values: [T1]) { self.init(pairs: values.map{ ($0, $0) }) }
    }

That is, I’d like to provide a convenience initializer that takes an array of values instead of pairs, and turns the values into pairs, IF THE TWO GENERIC TYPE PARAMETERS ARE THE SAME.

I can’t find a way to accomplish this. Is there one?

Thanks,

  Neil Faiman


(Karl) #2

Yes. You need to put it in an extension.

extension Foo where T1 == T2 {
    convenience init(values: [T1]){
    ….
    }
}

···

On 15 May 2016, at 14:45, Neil Faiman via swift-users <swift-users@swift.org> wrote:

Is it possible for a generic class to have methods (specifically, initializers) which are only defined if the generic parameters meet certain constratins?

Here’s a concrete example:

   class Foo <T1, T2> {
       init(pairs: [(T1, T2)]) {}
       // What I’d like to be able to doL
       convenience init "where T1 == T2" (values: [T1]) { self.init(pairs: values.map{ ($0, $0) }) }
   }

That is, I’d like to provide a convenience initializer that takes an array of values instead of pairs, and turns the values into pairs, IF THE TWO GENERIC TYPE PARAMETERS ARE THE SAME.

I can’t find a way to accomplish this. Is there one?

Thanks,

  Neil Faiman
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Neil Faiman) #3

Is this a relatively new language change? When I try it with the version of Swift that comes with Xcode 7.3.1, I get

    error: same-type requirement makes generic parameters 'T1' and 'T2' equivalent
    extension Foo where T1 == T2 {
                           ^

···

On May 15, 2016, at 1:33 PM, Karl <razielim@gmail.com> wrote:

Yes. You need to put it in an extension.

extension Foo where T1 == T2 {
   convenience init(values: [T1]){
   ….
   }
}

On 15 May 2016, at 14:45, Neil Faiman via swift-users <swift-users@swift.org> wrote:

Is it possible for a generic class to have methods (specifically, initializers) which are only defined if the generic parameters meet certain constratins?

Here’s a concrete example:

  class Foo <T1, T2> {
      init(pairs: [(T1, T2)]) {}
      // What I’d like to be able to doL
      convenience init "where T1 == T2" (values: [T1]) { self.init(pairs: values.map{ ($0, $0) }) }
  }

That is, I’d like to provide a convenience initializer that takes an array of values instead of pairs, and turns the values into pairs, IF THE TWO GENERIC TYPE PARAMETERS ARE THE SAME.

I can’t find a way to accomplish this. Is there one?


(Joe Groff) #4

Is this a relatively new language change? When I try it with the version of Swift that comes with Xcode 7.3.1, I get

   error: same-type requirement makes generic parameters 'T1' and 'T2' equivalent
   extension Foo where T1 == T2 {
                          ^

Unfortunately, it's a limitation of our type system today that class/struct/enum extensions can't use '==' constraints. It can often be worked around by making a protocol instead.

-Joe

···

On May 15, 2016, at 11:55 AM, Neil Faiman via swift-users <swift-users@swift.org> wrote:

On May 15, 2016, at 1:33 PM, Karl <razielim@gmail.com> wrote:

Yes. You need to put it in an extension.

extension Foo where T1 == T2 {
  convenience init(values: [T1]){
  ….
  }
}

On 15 May 2016, at 14:45, Neil Faiman via swift-users <swift-users@swift.org> wrote:

Is it possible for a generic class to have methods (specifically, initializers) which are only defined if the generic parameters meet certain constratins?

Here’s a concrete example:

class Foo <T1, T2> {
     init(pairs: [(T1, T2)]) {}
     // What I’d like to be able to doL
     convenience init "where T1 == T2" (values: [T1]) { self.init(pairs: values.map{ ($0, $0) }) }
}

That is, I’d like to provide a convenience initializer that takes an array of values instead of pairs, and turns the values into pairs, IF THE TWO GENERIC TYPE PARAMETERS ARE THE SAME.

I can’t find a way to accomplish this. Is there one?

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users