Protocol Arrays Adding vs. Instantiating


(Paul Ossenbruggen) #1

In swift 3.0 beta 3, I defined a fairly simple protocol and two structs
that implement it, if I initialize the array when creating the objects, it
works, but if I try to add elements I get an error:

Cannot convert value of type '[H]' to expected argument type 'inout _'

Shouldn't this work?

protocol H {

    var v : Int { get set }

    func hello()

}

struct J : H {

    var v : Int

    func hello() {

        print("j")

    }

}

struct K : H {

    var v : Int

    func hello() {

        print("k")

    }

}

let ag:[H] = [K(v:3), J(v:4)]

ag[0].hello()

ag[1].hello() //works

var af:[H] = []

af += [K(v:3)] // does not work

af += [J(v:4)]

af[0].hello()

af[1].hello()


(Paul Ossenbruggen) #2

Thanks to matt on stack overflow, you need to assign it to a temporary to
ensure the type is correct:

let w : H = K(v:3)

let x : H = J(v:3)

af += [w]

af += [x]

Is this worthy of a bug report? Or is it inherent in the design of the
language?

···

On Mon, Jul 25, 2016 at 1:02 PM, Paul Ossenbruggen <possen@gmail.com> wrote:

In swift 3.0 beta 3, I defined a fairly simple protocol and two structs
that implement it, if I initialize the array when creating the objects, it
works, but if I try to add elements I get an error:

Cannot convert value of type '[H]' to expected argument type 'inout _'

Shouldn't this work?

protocol H {

    var v : Int { get set }

    func hello()

}

struct J : H {

    var v : Int

    func hello() {

        print("j")

    }

}

struct K : H {

    var v : Int

    func hello() {

        print("k")

    }

}

let ag:[H] = [K(v:3), J(v:4)]

ag[0].hello()

ag[1].hello() //works

var af:[H] = []

af += [K(v:3)] // does not work

af += [J(v:4)]

af[0].hello()

af[1].hello()


(Team Nera) #3

Hi,
here are a few other ways that will compile:

af = af + [J(v:3)]
af += [J(v:4)] as [H]
af += [K(v:5)].map{ $0 as H }
af.append(K(v:6))

It does seem that "+=" does not trigger the inference of the type of the array literal the way "+" does. I don't know if that's a bug or one of those situations where you need to help the type system, the error seems a little bit too cryptic though.

It is by design that swift does not convert an array of concrete type to an array of protocol (it can take a long time), whereas single values are (like "w" and "x"). As I understand it, it's only because of the type inference on the array literal that its items are converted in the first two examples.

Nera

···

Le 25/07/2016 à 23:11, Paul Ossenbruggen via swift-users a écrit :

Thanks to matt on stack overflow, you need to assign it to a temporary to ensure the type is correct:

let w : H = K(v:3)

let x : H = J(v:3)

af += [w]

af += [x]

Is this worthy of a bug report? Or is it inherent in the design of the language?

On Mon, Jul 25, 2016 at 1:02 PM, Paul Ossenbruggen <possen@gmail.com > <mailto:possen@gmail.com>> wrote:

    In swift 3.0 beta 3, I defined a fairly simple protocol and two
    structs that implement it, if I initialize the array when creating
    the objects, it works, but if I try to add elements I get an error:

    Cannot convert value of type '[H]' to expected argument type 'inout _'

    Shouldn't this work?

    protocol H {

      var v : Int { get set }

      func hello()

    }

    struct J : H {

      var v : Int

      func hello() {

          print("j")

      }

    }

    struct K : H {

      var v : Int

      func hello() {

          print("k")

      }

    }

    let ag:[H] = [K(v:3), J(v:4)]

    ag[0].hello()

    ag[1].hello() //works

    var af:[H] = []

    af += [K(v:3)] // does not work

    af += [J(v:4)]

    af[0].hello()

    af[1].hello()

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