from Any? to Any

iLandesiLandes Membre
janvier 2017 modifié dans Objective-C, Swift, C, C++ #1

Bonjour,


 


J'ai un warning dans un prochain dont je ne comprends pas la signification :



Expression implicite coerced from Any? to Any

Mon idée est que j'envoie qq chose de type [key: String, value: Any?] dans  un dictionnaire de type [AnyHashable : Any]?


 


Comment mapper mon  [key: String, value: Any?] en  [key: String, value: Any] soit en supprimant les clés qui ont comme valeur nil soit en les retirant du tableau. Je pense qu'une fois les deux types identiques le warning va disparaitre.


 


Cela dit quelque chose à  quelqu'un ?


Mots clés:

Réponses

  • DrakenDraken Membre
    janvier 2017 modifié #2

    J'ai vu ce message apparaitre avec la dernière version d'XCode, en utilisant print().



    import UIKit

    class ViewController: UIViewController {

    var valeur:Int?

    override func viewDidLoad() {
    super.viewDidLoad()

    valeur = 123
    print (valeur)
    }
    }


    Le print(valeur) affiche le warning :


     



     


    Expression implicity coerced from "Int?" to Any



     


    Il me propose 3 manières de régler l'avertissement. J'ai pris celle-ci et ça roule :



    import UIKit

    class ViewController: UIViewController {

    var valeur:Int?

    override func viewDidLoad() {
    super.viewDidLoad()

    valeur = 123
    print (valeur as Any)
    }
    }


    Je présume que Xcode est devenu encore plus rigoureux qu'avant sur le contrôle des types de données.

  • Joanna CarterJoanna Carter Membre, Modérateur
    janvier 2017 modifié #3

    let x = [1 : nil, 2 : "fred", 3 : "bert", 4 : nil]

    let y = x.flatMap { return $1 != nil ? [$0 : $1!] : nil }

  • Joanna CarterJoanna Carter Membre, Modérateur


    J'ai vu ce message apparaitre avec la dernière version d'XCode, en utilisant print().



    import UIKit

    class ViewController: UIViewController {

    var valeur:Int?

    override func viewDidLoad() {
    super.viewDidLoad()

    valeur = 123
    print (valeur)
    }
    }


    Le print(valeur) affiche le warning :


     


     


    Il me propose 3 manières de régler l'avertissement. J'ai pris celle-ci et ça roule :



    import UIKit

    class ViewController: UIViewController {

    var valeur:Int?

    override func viewDidLoad() {
    super.viewDidLoad()

    valeur = 123
    print (valeur as Any)
    }
    }


    Je présume que Xcode est devenu encore plus rigoureux qu'avant sur le contrôle des types de données.




     


    Car tu as assigné une valeur juste avant le print(...), tu peux, en toute sécurité, utiliser :



    valeur = 123

    print(valeur!)



  • let x = [1 : nil, 2 : "fred", 3 : "bert", 4 : nil]

    let y = x.flatMap { return $1 != nil ? [$0 : $1!] : nil }



     


    Merci Joanna mais plutôt 



    let x = [1 : nil, 2 : "fred", 3 : "bert", 4 : nil]
    let y = x.flatMap { return $1 != nil ? ($0,$1!) : nil }

    Sinon avec les [ on recrée un tableau ;-)

  • iLandesiLandes Membre
    janvier 2017 modifié #6

    Grr non plus là  on créé un tableau de turple (int:string!) :[


  • Joanna CarterJoanna Carter Membre, Modérateur
    janvier 2017 modifié #7

    Avec mon code, tu commences avec un tableau de dictionnaires - et, après, tu auras un tableau de dictionnaires.


     


    Le [$0 : $1!] est un dictionnaire de [Int : String]


     


    Donc, qu'est-ce que tu veux ?


  • iLandesiLandes Membre
    janvier 2017 modifié #8



    Avec mon code, tu commences avec un tableau de dictionnaires - et, après, tu auras un tableau de dictionnaires.




     


    En fait non  ::)



    x = [2: Optional("fred"), 3: Optional("bert"), 1: nil, 4: nil]
    y = [[2, "fred"], [3, "bert"]]

     je voudrais :



    x = [2: Optional("fred"), 3: Optional("bert"), 1: nil, 4: nil]
    y = [2: "fred", 3: "bert"]

  • DrakenDraken Membre
    janvier 2017 modifié #9


     


    Car tu as assigné une valeur juste avant le print(...), tu peux, en toute sécurité, utiliser :



    valeur = 123

    print(valeur!)



    Oui je sais, mais j'ai vraiment une aversion pour le !. Je trouve que cela ne fait pas propre dans un code.


     


    EDIT : De plus je n'ai pas rencontré le problème avec un Int?. Là  c'est juste un exemple simplifié pour montrer l'apparition du warning. En situation réelle cela se produit avec des objets pouvant vraiment être nil.

  • Joanna CarterJoanna Carter Membre, Modérateur
    janvier 2017 modifié #10

    OK iLandes, c'est une merveille de programmation fonctionnelle :



    let x = [1 : nil, 2 : "fred", 3 : "bert", 4 : nil]

    let y = x.reduce([Int : String](),
    {
    var result = $0

    if let value = $1.value
    {
    result[$1.key] = value
    }

    return result
    })

    :D   :D   :D


  • Merci Joanna ;-)


     


    Pour les print je fais cela :



    var s: String?
    print(s ?? "nil")
    // "nil"
    s = "test"
    print(s ?? "nil")
    // test
  • Joanna CarterJoanna Carter Membre, Modérateur


    Merci Joanna ;-)




     


    Tu comprends ce qui fait le code dans le closure ? Ce n'était pas facile à  trouver et, même moi, j'arrive à  peine à  le comprendre  ???  ::)

  • iLandesiLandes Membre
    janvier 2017 modifié #13

    Pour être plus concret j'ai modifier un eu l'exemple avec des données comme cela :



    import Foundation
    let d = Date()
    let x:[String : Any?] = ["Nom" : "JeanSairien", "Age" : 35, "Sex" : nil, "update" : d]
    let y = x.reduce([String : Any](),
                     {
                        var result = $0
                        
                        if let value = $1.value
                        {
                            result[$1.key] = value
                        }
                        
                        return result
    })


    print (x)
    print (y)

    La sortie de console donne



    ["Nom": Optional("JeanSairien"), "Sex": nil, "update": Optional(2017-01-28 18:07:52 +0000), "Age": Optional(35)]
    ["Nom": "JeanSairien", "update": 2017-01-28 18:07:52 +0000, "Age": 35]

    En gros X est un tableau avec des infos clé/valeur de type [String:Any?]. Les clés sont en string et les valeurs en n'importe quoi (string, date, int...)


     


    Y retire les clé/valeur quand la valeur est nil. On obtient donc un tableau clé/valeur de type [String:Any] débarrasser des clé/valeur non renseignée.


     


     


    Je vois grosso modo ce que fait ton code bien que j'ai du mal à  identifier $0 qui est [String : Any] et $1 qui est (key : String, value : any?) dans cette histoire.


     


    Quoi qu'il en soit vous devez vous demander pourquoi faire tout cela pour résoudre mon problème initial de warning : 



    Expression implicite coerced from Any? to Any

    Le méchant compilateur n'est pas très coopératif en ne donnant pas clairement la ligne de se warning, juste la classe.  >:(


     


    Je me servais plus loin dans mon code de se tableau pour poster une notification comme ceci :



    // WARNING
    NotificationCenter.default.post(name: FormNotification.ValueChange, object: nil, userInfo: x)

    Maintenant je la poste comme ceci:



    NotificationCenter.default.post(name: FormNotification.ValueChange, object: nil, userInfo: y)

    Evidement je n'utilise pas x ou y comme nom dans mon projet définit mais un nom plus explicite :]


     


    Grace aux code de Larme qui transform x en le warning disparait  :D


     


    Tordu ou pas ?


  • Joanna CarterJoanna Carter Membre, Modérateur


    En gros X est un tableau avec des infos clé/valeur de type [String:Any?]. Les clés sont en string et les valeurs en n'importe quoi (string, date, int...)




     


    Si je me permet ? X n'est pas un tableau, c'est un dictionnaire. On peut, quand-même, dire que les sont la même chose mais, c'est une différence assez importante  8--)

  • Oui un dictionnaire tu as raison je suis dans l'euphorie de retrouver un projet sans warning.


     


    Reste à  résoudre pour mes connaissance personnelles d'où sorte ce $0, $1 c'est le seul truc que je pige pas bien dans ton code


     


    Merci beaucoup !


  • Joanna CarterJoanna Carter Membre, Modérateur

    Voilà  bon !


     


    Le code avec les paramètres nommés à  la place des paramètres anonymes :



    let d = Date()

    let x:[String : Any?] = ["Nom" : "JeanSairien", "Age" : 35, "Sex" : nil, "update" : d]

    let y = x.reduce([String : Any](),
    {
    (nextPartialResult: [String : Any], element: (key: String, value: Any?)) -> [String : Any] in

    var result = nextPartialResult

    if let value = element.value
    {
    result[element.key] = value
    }

    return result
    })
Connectez-vous ou Inscrivez-vous pour répondre.