Enum associated value confusing









up vote
2
down vote

favorite












When I try use func obj func, I get the error:




Cannot invoke 'obj' with an argument list of type '(message: (QueueAddable))'




I'm confused with Swift types.
Obj func used to get concrete type for decode.



protocol QueueAddable: Encodable 
var playlistsCollection:String? get
var playlists: [String]? get


struct Playlist: QueueAddable
var playlistsCollection:String?
return "id"

var playlists: [String]?
return ["id", "id2"]

private enum CodingKeys:String,CodingKey
case playlistsCollection
case playlists


public func encode(to encoder: Encoder) throws
var values = encoder.container(keyedBy: CodingKeys.self)
try values.encode(playlistsCollection, forKey: Playlist.CodingKeys.playlistsCollection)
try values.encode(playlists, forKey: .playlists)



func obj<Q>(message: Q) where Q: QueueAddable
let encoder = JSONEncoder()
let data = try! encoder.encode(message)


enum SomeEnum
case playlist(QueueAddable)
func doSome() throws -> Data
switch self
case .playlist(let queueAddable):
let encoder = JSONEncoder()

// Error on the following line:
obj(message: queueAddable)
return Data()




let playlist = Playlist()
let data = try SomeEnum.playlist(playlist).doSome()









share|improve this question



















  • 1




    obj is expecting some type that implements QueueAddable, but you're sending value that "is of type" QueueAddable. Protocols do not implement themselves, therefore obj cannot be called with message: QueueAddable.
    – user28434
    Nov 9 at 15:32














up vote
2
down vote

favorite












When I try use func obj func, I get the error:




Cannot invoke 'obj' with an argument list of type '(message: (QueueAddable))'




I'm confused with Swift types.
Obj func used to get concrete type for decode.



protocol QueueAddable: Encodable 
var playlistsCollection:String? get
var playlists: [String]? get


struct Playlist: QueueAddable
var playlistsCollection:String?
return "id"

var playlists: [String]?
return ["id", "id2"]

private enum CodingKeys:String,CodingKey
case playlistsCollection
case playlists


public func encode(to encoder: Encoder) throws
var values = encoder.container(keyedBy: CodingKeys.self)
try values.encode(playlistsCollection, forKey: Playlist.CodingKeys.playlistsCollection)
try values.encode(playlists, forKey: .playlists)



func obj<Q>(message: Q) where Q: QueueAddable
let encoder = JSONEncoder()
let data = try! encoder.encode(message)


enum SomeEnum
case playlist(QueueAddable)
func doSome() throws -> Data
switch self
case .playlist(let queueAddable):
let encoder = JSONEncoder()

// Error on the following line:
obj(message: queueAddable)
return Data()




let playlist = Playlist()
let data = try SomeEnum.playlist(playlist).doSome()









share|improve this question



















  • 1




    obj is expecting some type that implements QueueAddable, but you're sending value that "is of type" QueueAddable. Protocols do not implement themselves, therefore obj cannot be called with message: QueueAddable.
    – user28434
    Nov 9 at 15:32












up vote
2
down vote

favorite









up vote
2
down vote

favorite











When I try use func obj func, I get the error:




Cannot invoke 'obj' with an argument list of type '(message: (QueueAddable))'




I'm confused with Swift types.
Obj func used to get concrete type for decode.



protocol QueueAddable: Encodable 
var playlistsCollection:String? get
var playlists: [String]? get


struct Playlist: QueueAddable
var playlistsCollection:String?
return "id"

var playlists: [String]?
return ["id", "id2"]

private enum CodingKeys:String,CodingKey
case playlistsCollection
case playlists


public func encode(to encoder: Encoder) throws
var values = encoder.container(keyedBy: CodingKeys.self)
try values.encode(playlistsCollection, forKey: Playlist.CodingKeys.playlistsCollection)
try values.encode(playlists, forKey: .playlists)



func obj<Q>(message: Q) where Q: QueueAddable
let encoder = JSONEncoder()
let data = try! encoder.encode(message)


enum SomeEnum
case playlist(QueueAddable)
func doSome() throws -> Data
switch self
case .playlist(let queueAddable):
let encoder = JSONEncoder()

// Error on the following line:
obj(message: queueAddable)
return Data()




let playlist = Playlist()
let data = try SomeEnum.playlist(playlist).doSome()









share|improve this question















When I try use func obj func, I get the error:




Cannot invoke 'obj' with an argument list of type '(message: (QueueAddable))'




I'm confused with Swift types.
Obj func used to get concrete type for decode.



protocol QueueAddable: Encodable 
var playlistsCollection:String? get
var playlists: [String]? get


struct Playlist: QueueAddable
var playlistsCollection:String?
return "id"

var playlists: [String]?
return ["id", "id2"]

private enum CodingKeys:String,CodingKey
case playlistsCollection
case playlists


public func encode(to encoder: Encoder) throws
var values = encoder.container(keyedBy: CodingKeys.self)
try values.encode(playlistsCollection, forKey: Playlist.CodingKeys.playlistsCollection)
try values.encode(playlists, forKey: .playlists)



func obj<Q>(message: Q) where Q: QueueAddable
let encoder = JSONEncoder()
let data = try! encoder.encode(message)


enum SomeEnum
case playlist(QueueAddable)
func doSome() throws -> Data
switch self
case .playlist(let queueAddable):
let encoder = JSONEncoder()

// Error on the following line:
obj(message: queueAddable)
return Data()




let playlist = Playlist()
let data = try SomeEnum.playlist(playlist).doSome()






swift enums associated-value






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 9 at 15:24









rmaddy

234k27305371




234k27305371










asked Nov 9 at 15:06









Drugan

336




336







  • 1




    obj is expecting some type that implements QueueAddable, but you're sending value that "is of type" QueueAddable. Protocols do not implement themselves, therefore obj cannot be called with message: QueueAddable.
    – user28434
    Nov 9 at 15:32












  • 1




    obj is expecting some type that implements QueueAddable, but you're sending value that "is of type" QueueAddable. Protocols do not implement themselves, therefore obj cannot be called with message: QueueAddable.
    – user28434
    Nov 9 at 15:32







1




1




obj is expecting some type that implements QueueAddable, but you're sending value that "is of type" QueueAddable. Protocols do not implement themselves, therefore obj cannot be called with message: QueueAddable.
– user28434
Nov 9 at 15:32




obj is expecting some type that implements QueueAddable, but you're sending value that "is of type" QueueAddable. Protocols do not implement themselves, therefore obj cannot be called with message: QueueAddable.
– user28434
Nov 9 at 15:32












1 Answer
1






active

oldest

votes

















up vote
1
down vote



accepted










I think the problem is that the function expects a type and not a protocol. If you make the enum generic using a type that implements the protocol it will work.



Change the enum's first two lines like this:



enum SomeEnum<Q : QueueAddable> {
case playlist(Q)


I tested in the following playground:



import Foundation

protocol QueueAddable: Encodable
var playlistsCollection:String? get
var playlists: [String]? get


struct Playlist: QueueAddable
var playlistsCollection:String?
return "id"

var playlists: [String]?
return ["id", "id2"]

private enum CodingKeys:String,CodingKey
case playlistsCollection
case playlists


public func encode(to encoder: Encoder) throws
var values = encoder.container(keyedBy: CodingKeys.self)
try values.encode(playlistsCollection, forKey: Playlist.CodingKeys.playlistsCollection)
try values.encode(playlists, forKey: .playlists)



func obj<Q>(message: Q) where Q: QueueAddable
let encoder = JSONEncoder()
let data = try! encoder.encode(message)


enum SomeEnum<Q : QueueAddable>
case playlist(Q)
func doSome() throws -> Data
switch self
case .playlist(let queueAddable):
let encoder = JSONEncoder()

// No longer error on the following line:
obj(message: queueAddable)
return Data()




let playlist = Playlist()
let data = try SomeEnum.playlist(playlist).doSome()


Hope it helps!






share|improve this answer




















    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53228267%2fenum-associated-value-confusing%23new-answer', 'question_page');

    );

    Post as a guest






























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    1
    down vote



    accepted










    I think the problem is that the function expects a type and not a protocol. If you make the enum generic using a type that implements the protocol it will work.



    Change the enum's first two lines like this:



    enum SomeEnum<Q : QueueAddable> {
    case playlist(Q)


    I tested in the following playground:



    import Foundation

    protocol QueueAddable: Encodable
    var playlistsCollection:String? get
    var playlists: [String]? get


    struct Playlist: QueueAddable
    var playlistsCollection:String?
    return "id"

    var playlists: [String]?
    return ["id", "id2"]

    private enum CodingKeys:String,CodingKey
    case playlistsCollection
    case playlists


    public func encode(to encoder: Encoder) throws
    var values = encoder.container(keyedBy: CodingKeys.self)
    try values.encode(playlistsCollection, forKey: Playlist.CodingKeys.playlistsCollection)
    try values.encode(playlists, forKey: .playlists)



    func obj<Q>(message: Q) where Q: QueueAddable
    let encoder = JSONEncoder()
    let data = try! encoder.encode(message)


    enum SomeEnum<Q : QueueAddable>
    case playlist(Q)
    func doSome() throws -> Data
    switch self
    case .playlist(let queueAddable):
    let encoder = JSONEncoder()

    // No longer error on the following line:
    obj(message: queueAddable)
    return Data()




    let playlist = Playlist()
    let data = try SomeEnum.playlist(playlist).doSome()


    Hope it helps!






    share|improve this answer
























      up vote
      1
      down vote



      accepted










      I think the problem is that the function expects a type and not a protocol. If you make the enum generic using a type that implements the protocol it will work.



      Change the enum's first two lines like this:



      enum SomeEnum<Q : QueueAddable> {
      case playlist(Q)


      I tested in the following playground:



      import Foundation

      protocol QueueAddable: Encodable
      var playlistsCollection:String? get
      var playlists: [String]? get


      struct Playlist: QueueAddable
      var playlistsCollection:String?
      return "id"

      var playlists: [String]?
      return ["id", "id2"]

      private enum CodingKeys:String,CodingKey
      case playlistsCollection
      case playlists


      public func encode(to encoder: Encoder) throws
      var values = encoder.container(keyedBy: CodingKeys.self)
      try values.encode(playlistsCollection, forKey: Playlist.CodingKeys.playlistsCollection)
      try values.encode(playlists, forKey: .playlists)



      func obj<Q>(message: Q) where Q: QueueAddable
      let encoder = JSONEncoder()
      let data = try! encoder.encode(message)


      enum SomeEnum<Q : QueueAddable>
      case playlist(Q)
      func doSome() throws -> Data
      switch self
      case .playlist(let queueAddable):
      let encoder = JSONEncoder()

      // No longer error on the following line:
      obj(message: queueAddable)
      return Data()




      let playlist = Playlist()
      let data = try SomeEnum.playlist(playlist).doSome()


      Hope it helps!






      share|improve this answer






















        up vote
        1
        down vote



        accepted







        up vote
        1
        down vote



        accepted






        I think the problem is that the function expects a type and not a protocol. If you make the enum generic using a type that implements the protocol it will work.



        Change the enum's first two lines like this:



        enum SomeEnum<Q : QueueAddable> {
        case playlist(Q)


        I tested in the following playground:



        import Foundation

        protocol QueueAddable: Encodable
        var playlistsCollection:String? get
        var playlists: [String]? get


        struct Playlist: QueueAddable
        var playlistsCollection:String?
        return "id"

        var playlists: [String]?
        return ["id", "id2"]

        private enum CodingKeys:String,CodingKey
        case playlistsCollection
        case playlists


        public func encode(to encoder: Encoder) throws
        var values = encoder.container(keyedBy: CodingKeys.self)
        try values.encode(playlistsCollection, forKey: Playlist.CodingKeys.playlistsCollection)
        try values.encode(playlists, forKey: .playlists)



        func obj<Q>(message: Q) where Q: QueueAddable
        let encoder = JSONEncoder()
        let data = try! encoder.encode(message)


        enum SomeEnum<Q : QueueAddable>
        case playlist(Q)
        func doSome() throws -> Data
        switch self
        case .playlist(let queueAddable):
        let encoder = JSONEncoder()

        // No longer error on the following line:
        obj(message: queueAddable)
        return Data()




        let playlist = Playlist()
        let data = try SomeEnum.playlist(playlist).doSome()


        Hope it helps!






        share|improve this answer












        I think the problem is that the function expects a type and not a protocol. If you make the enum generic using a type that implements the protocol it will work.



        Change the enum's first two lines like this:



        enum SomeEnum<Q : QueueAddable> {
        case playlist(Q)


        I tested in the following playground:



        import Foundation

        protocol QueueAddable: Encodable
        var playlistsCollection:String? get
        var playlists: [String]? get


        struct Playlist: QueueAddable
        var playlistsCollection:String?
        return "id"

        var playlists: [String]?
        return ["id", "id2"]

        private enum CodingKeys:String,CodingKey
        case playlistsCollection
        case playlists


        public func encode(to encoder: Encoder) throws
        var values = encoder.container(keyedBy: CodingKeys.self)
        try values.encode(playlistsCollection, forKey: Playlist.CodingKeys.playlistsCollection)
        try values.encode(playlists, forKey: .playlists)



        func obj<Q>(message: Q) where Q: QueueAddable
        let encoder = JSONEncoder()
        let data = try! encoder.encode(message)


        enum SomeEnum<Q : QueueAddable>
        case playlist(Q)
        func doSome() throws -> Data
        switch self
        case .playlist(let queueAddable):
        let encoder = JSONEncoder()

        // No longer error on the following line:
        obj(message: queueAddable)
        return Data()




        let playlist = Playlist()
        let data = try SomeEnum.playlist(playlist).doSome()


        Hope it helps!







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 2 days ago









        acyrman

        1166




        1166



























             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53228267%2fenum-associated-value-confusing%23new-answer', 'question_page');

            );

            Post as a guest














































































            Popular posts from this blog

            Kleinkühnau

            Makov (Slowakei)

            Deutsches Schauspielhaus