2014-10-14 17 views
16

Czy jest możliwe wymaganie, aby określone wystąpienia typów ogólnych były zgodne z protokołem w Swift?Typ ogólny zgodny z protokołem w Swift

Załóżmy na przykład, że mam ogólny typ o nazwie Thing<T>. Chcę, aby Thing<Int> był zgodny z określonym protokołem, ale nie Thing<T>.

+1

brzmi jak rodzaj magii, którą chcesz – bandejapaisa

+0

'Thing '; 'Rzecz '; 'Rzecz Te nie działają, ale to jest coś, co chciałbyś napisać, prawda? Myślę, że najbliższym, co możesz teraz uzyskać, jest sprawdzenie zgodności w niezalecanym inicjatorze i powrót do zera, gdy zgodność nie spełnia twoich wymagań. –

+1

Pytasz o [ConstraintKinds] (https://www.haskell.org/ghc/docs/7.4.1/html/users_guide/constraint-kind.html), które są cechą systemów o wyższym typie. Biorąc pod uwagę, że nie mamy nawet regularnych rodzajów, nie mówiąc już o typach rodzin, naprawdę nie ma na to sposobu. – CodaFi

Odpowiedz

-3

Można zrobić coś takiego, jak przy użyciu słowa kluczowego where i przekazać warunkowe poświadczenia. Widziałem to pod Gdzie sekcja Klauzule https://developer.apple.com/library/mac/documentation/Swift/Conceptual/Swift_Programming_Language/Generics.html#//apple_ref/doc/uid/TP40014097-CH26-XID_275

class Thing<T : SomeProtocol where reflect(T).summary != "Int"> { 
    ... 
} 
+2

Klauzula 'where' w wiązaniach typu akceptuje tylko warunki': 'i' == 'i są one oceniane podczas kompilacji. ('reflect (T) .summary! =" Int "' jest wyrażeniem wykonawczym) –

2

W Swift 2.0 można rozszerzyć protokołów i typów

Kiedy przedłużyć go można dodawać rodzajowe where ograniczeń. Tylko typy, które pasuje do tego zasada będzie w stanie wykorzystać tę funkcjonalność

Przykład:

public struct Thing<T> { 
    let x: T 
} 

extension Thing where T : IntegerType { 
    func giveMeInt() -> T { 
    return x 
    } 
} 

let a = Thing<Int>(x: 10) 
a.giveMeInt() 

let b = Thing(x: 10.1) 
//b.giveMeInt() // Error 

W ten sposób można dodać dodatkową funkcjonalność Thing<Int> typu

nie wiem drogę aby dostosować się do protokołu w rozszerzeniu, ale nie ma to większego sensu.

Ograniczenie: Generic where T : może być używana z protokołami i klas, dlatego nie możemy określić Int tam

+2

Niestety to nie odpowiada na jego pytanie, ponieważ chce, aby Thing dostosował się do określonych protokołów w odniesieniu do T. – Qbyte

+0

Wiem, chciałem tylko pokazać że to możliwe. Sądzę również, że powinieneś obejrzeć sesję WWDC15 z protokołem programowania zorientowanego na protokół. Sensowne jest dodanie konformacji protokołu w rozszerzeniu do określonego generycznego kodu. –

+0

Nie, nie pokazano ** jest ** możliwe. Pokazałeś tylko, że coś jest możliwe, co nie jest tak naprawdę związane z pytaniem.Chodziło o to, aby typowy typ był zgodny z protokołem, aw twojej odpowiedzi nie ma nawet protokołu, nigdzie. To dobra odpowiedź ... ale na zupełnie inne pytanie. Uczynienie obiektu zgodnym z protokołem przez rozszerzenie jest czymś, co prawdopodobnie wie. Chciała wiedzieć, jak to się robi dla leków generycznych. – Mecki

3

dobrze, to może nie być zbyt uciążliwe, a może to być dość oczywiste, że masz ignorowane, ale można zrobić „specyficzny konkretyzacji typu rodzajowego” - jako:

class ThingOfInt : Thing<Int>, SpecialIntProtocol { 
// implement SpecialIntProtocol (if it isn't already 
// implemented in an extension) 
} 

lub nieco więcej ogólności:

class IntThing<T:IntegerType> : MyThing<T>, SpecialIntProtocol { 
} 
+0

To niefortunne, że nie jest to odpowiedź ogólna, ponieważ typ, który chcę ograniczyć, jest "wyliczeniem", a zatem nie można go zklasyfikować. Jak w "Jeśli wyliczenie ma typ" Int ", spraw, aby było zgodne z protokołem" X "" – Mazyod

+0

To jest kolejna miła i prawidłowa odpowiedź ... jeszcze na inne pytanie :-( – Mecki

Powiązane problemy