2017-09-29 3 views
2

Je suis donc en train d'apprendre le swift pour un nouveau travail et de travailler sur une vue tabulaire statique et j'ai décidé d'utiliser des tuples pour suivre la cellule a été sélectionné. Cependant je reçois l'erreur suivante:Boîtier de commutateur de tuple Swift: le type de modèle ne peut pas correspondre aux valeurs de type

Expression pattern of type '(section: Int, row: Int)' cannot match values of type '(section: Int, row: Int)'

Cette erreur est le résultat du code simplifié suivant

let ABOUTPROTECTIONCELL = (section: 1, row: 0) 
    let cellIdentifier = (section: indexPath.section, row: indexPath.row) 

    switch cellIdentifier { 
    case ABOUTPROTECTIONCELL: 
     print("here") 
    default: 
     print("bleh") 
    } 

Ce qui est vraiment déroutant est que lorsque j'utilise les éléments suivants « si » au lieu de un tout instruction switch fonctionne très bien le programme fonctionne très bien ...

if (cellIdentifier == CELL_ONE) { 
     print("cell1") 
    } else if (cellIdentifier == CELL_TWO) { 
     print("cell2") 
    } else if (cellIdentifier == CELL_THREE) { 
     print("cell3") 
    } 

Est-il possible de le faire avec une instruction switch que je trouve que plus élégant que l'instruction if? Très curieux de savoir pourquoi cela ne fonctionne pas tel quel. Merci d'avance!

+1

Votre code ne compile pas parce que tuples ne sont pas 'Equatable'. Voir [Pourquoi ne puis-je pas utiliser une constante de tuple comme cas dans une instruction switch] (https://stackoverflow.com/questions/29677991/why-cant-i-use-a-tuple-constant-as-a- case-in-a-switch-statement). –

+0

Si elles ne sont pas équivalentes, pourquoi l'instruction if est-elle compilée et exécutée? C'est ce qui me déroute. –

+0

Il existe un opérateur '==' pour les tuples, mais les tuples ne sont pas conformes à un protocole. - En outre: Le protocole Equatable garantit l'existence d'un opérateur ===, mais un opérateur '== n'implique pas la conformité à Equatable –

Répondre

2

Solution 1

let ABOUTTROVPROTECTIONCELL = (section: 1, row: 0) 
let cellIdentifier = (section: indexPath.section, row: indexPath.row) 

switch cellIdentifier { 
case (ABOUTTROVPROTECTIONCELL.section, ABOUTTROVPROTECTIONCELL.row): 
    print("here") 
default: 
    print("bleh") 
} 

Solution 2

Il suffit d'utiliser IndexPath struct et son initialiseur pour créer ABOUTTROVPROTECTIONCELL

let ABOUTTROVPROTECTIONCELL = IndexPath(row: 0, section: 1) 
let cellIdentifier = indexPath // Not necessary, you can just use indexPath instead 

switch cellIdentifier { 
case ABOUTTROVPROTECTIONCELL: 
    print("here") 
default: 
    print("bleh") 
} 

Solution 3

Mettre en oeuvre ~= func pour votre tuple:

typealias IndexPathTuple = (section: Int, row: Int) 
func ~=(a: IndexPathTuple, b: IndexPathTuple) -> Bool { 
    return a.section ~= b.section && a.row ~= b.row 
} 

let ABOUTTROVPROTECTIONCELL = (section: 1, row: 0) 
let cellIdentifier = (section: indexPath.section, row: indexPath.row) 

switch cellIdentifier { 
case ABOUTTROVPROTECTIONCELL: 
    print("here") 
default: 
    print("bleh") 
} 
+0

Votre premier cas peut être réécrit comme' switch cellIdentifier { case (ABOUTTROVPROTECTIONCELL.section , ABOUTTROVPROTECTIONCELL.row): ' –

+0

@MidhunMP, oui, merci. –