240 votes

Comment puis-je étendre des tableaux dactylographiés dans Swift?

Comment puis-je prolonger Swift Array<T> ou T[] type personnalisé fonctionnelle utils?

Navigation autour de Swift API docs montre que les méthodes de Tableau sont une extension de l' T[], e.g:

extension T[] : ArrayType {
    //...
    init()

    var count: Int { get }

    var capacity: Int { get }

    var isEmpty: Bool { get }

    func copy() -> T[]
}

Lors de la copie et le collage de la même source et d'essayer toutes les variantes comme:

extension T[] : ArrayType {
    func foo(){}
}

extension T[] {
    func foo(){}
}

Il ne parvient pas à construire avec l'erreur:

De type Nominal T[] ne peut pas être prolongé

En utilisant la totalité de la définition de type échoue avec l' Use of undefined type 'T',, je.e:

extension Array<T> {
    func foo(){}
}

Et c'est aussi ne pas avec Array<T : Any> et Array<String>.

Curieusement Swift me permet de prolonger un non tableau avec:

extension Array {
    func each(fn: (Any) -> ()) {
        for i in self {
            fn(i)
        }
    }
}

Qui cela me permet d'appeler avec:

[1,2,3].each(println)

Mais je ne peux pas créer un véritable générique type d'extension que le type semble être perdu quand il coule à travers la méthode, de l'e.g essayer de remplacer Swift filtre intégré avec:

extension Array {
    func find<T>(fn: (T) -> Bool) -> T[] {
        var to = T[]()
        for x in self {
            let t = x as T
            if fn(t) {
                to += t
            }
        }
        return to
    }
}

Mais le compilateur traite comme non typée où il permet l'appel de l'extension:

["A","B","C"].find { $0 > "A" }

Et quand on marchait à l'aide d'un débogueur indique le type est - Swift.String mais c'est une erreur d'essayer d'accès comme une Chaîne sans moulage String tout d'abord, je.e:

["A","B","C"].find { ($0 as String).compare("A") > 0 }

Personne ne sait quelle est la bonne manière de créer un typée méthode d'extension qui agit comme des extensions internes?

64voto

mythz Points 54874

Après avoir essayé différentes choses, la solution semble supprimer les <T> de la signature, comme ceci:

 extension Array {
    func find(fn: (T) -> Bool) -> [T] {
        var to = [T]()
        for x in self {
            let t = x as T;
            if fn(t) {
                to += t
            }
        }
        return to
    }
}
 

Ce qui fonctionne maintenant comme prévu sans erreurs de construction:

 ["A","B","C"].find { $0.compare("A") > 0 }
 

5voto

Encore PTL Points 1108

Si vous souhaitez en savoir plus sur l'extension des tableaux et d'autres types de code de validation de classes intégrées dans ce référentiel github https://github.com/ankurp/Dollar.swift/tree/master/Cent/Cent

A partir de Xcode 6.1, la syntaxe pour étendre les tableaux est la suivante

 extension Array {
    func at(indexes: Int...) -> [Element] {
        ... // You code goes herer
    }
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X