Kiedy próbujesz zrozumieć program lub w niektórych przypadkach narożnych, warto być w stanie dowiedzieć się, jakiego typu jest coś. Wiem, że debuger może wyświetlać pewne informacje o typie, i zwykle możesz polegać na wnioskowaniu o typie, aby uniknąć nieokreślania typu w takich sytuacjach, ale nadal naprawdę chciałbym mieć coś takiego jak Pythontype()
dynamicType (patrz to pytanie )
Aktualizacja: zostało to zmienione w najnowszej wersji Swift, obj.dynamicType
teraz zawiera odniesienie do typu, a nie wystąpienia typu dynamicznego.
Ten wydaje się najbardziej obiecujący, ale do tej pory nie byłem w stanie znaleźć faktycznego typu
class MyClass {
var count = 0
}
let mc = MyClass()
# update: this now evaluates as true
mc.dynamicType === MyClass.self
Próbowałem również za pomocą odniesienia do instancji klasy nowy obiekt, który robi pracę, ale dziwnie dał mi błąd mówiąc, muszę dodać required
inicjator:
Pracuje:
class MyClass {
var count = 0
required init() {
}
}
let myClass2 = MyClass.self
let mc2 = MyClass2()
Jednak wciąż jest to tylko mały krok w kierunku odkrycia rodzaju dowolnego obiektu
edycja : usunąłem znaczną liczbę nieistotnych już szczegółów - spójrz na historię edycji, jeśli jesteś zainteresowany :)
źródło
print(mc)
czydump(mc)
będzie wydrukować podsumowanie (które można uzyskać ztoString(mc)
lubreflect(mc).summary
), która będzie zawierać nazwę klasy gdzieś tam. Ale nie jest jasne, jak samemu zdobyć nazwę klasy.Odpowiedzi:
Wersja Swift 3:
źródło
var myVar: SomeType!
. Kompilator wyświetla błąd „Nie można przekonwertować wartości typu„ SomeType! .Type ”(alias„ ImplicitlyUnwrappedOptional <SomeType> .Type ”) na oczekiwany typ argumentu„ AnyClass ”(alias„ AnyObject.Type ”). Kompilator sugeruje dodanieas! AnyClass
po typie, ale następnie program ulega awarii z pewnym „EXC_BAD_INSTRUCTION” i innym dżibrem, którego nie mogę rozszyfrowaćString
który jest przekazywany jako typ,Any
totype(of:)
wyświetliAny
, a nieString
.Swift 2.0:
Właściwym sposobem na przeprowadzenie tego rodzaju introspekcji jest użycie struktury Mirror ,
Następnie, aby uzyskać dostęp do samego typu ze
Mirror
struktury, użyj właściwości w następującysubjectType
sposób:Następnie możesz użyć czegoś takiego:
źródło
String
iOptional(String)
nie są takie same.dynamicType.printClassName
Kod jest od przykładu w książce Swift. Nie ma możliwości, aby bezpośrednio pobrać niestandardową nazwę klasy, ale możesz sprawdzić typ instancji za pomocąis
słowa kluczowego, jak pokazano poniżej. Ten przykład pokazuje również, jak zaimplementować niestandardową funkcję className, jeśli naprawdę chcesz, aby nazwa klasy była łańcuchem.Uwaga:
te podklasy
NSObject
już implementują własną funkcję className. Jeśli pracujesz z Cocoa, możesz po prostu użyć tej właściwości.źródło
subjectType
nie jest już dostępny idynamicType
powoduje komunikat przestarzałego kompilatora.Począwszy od Xcode 6.0.1 (przynajmniej nie jestem pewien, kiedy go dodali), twój oryginalny przykład działa teraz:
Aktualizacja:
Aby odpowiedzieć na oryginalne pytanie, możesz z powodzeniem używać środowiska wykonawczego Objective-C z prostymi obiektami Swift.
Spróbuj wykonać następujące czynności:
źródło
Jeśli musisz po prostu sprawdzić, czy zmienna jest typu X lub czy jest zgodna z jakimś protokołem, możesz użyć
is
lubas?
jak poniżej:Jest to równoważne z
isKindOfClass
Obj-C.I to jest równoważne z
conformsToProtocol
lubisMemberOfClass
źródło
as?
rzutowaniem warunkowym działaisKindOfClass
również tak samo, tylko zapewnia wynik rzutowania, jeśli zakończy się powodzeniem.isMemberOfClass
jest warunekobject.dynamicType == ClassName.self
.Swift 3:
źródło
is
istnieje przed Swift 3 ...?Dla Swift 3.0
Dla Swift 2.0 - 2.3
źródło
Oto dwa sposoby, które polecam to zrobić:
Lub:
Oto szczegółowy przykład:
źródło
print( aShape is Square )
,is
operator jest bardziej preferowany.Zależy od przypadku użycia. Załóżmy jednak, że chcesz zrobić coś użytecznego z typami „zmiennymi”.
switch
Oświadczenie Swift jest bardzo potężne i może pomóc uzyskać wyniki, których szukasz ...W takim przypadku należy mieć prosty słownik, który zawiera pary klucz / wartość, które mogą być UInt, Int lub String. W
.filter()
metodzie w słowniku muszę się upewnić, że poprawnie testuję wartości i testuję tylko ciąg znaków, gdy jest to ciąg znaków itp. Instrukcja switch sprawia, że jest to proste i bezpieczne! Przypisując 9 do zmiennej typu Any, powoduje przełączenie na Int. Spróbuj zmienić na:... i spróbuj ponownie. Tym razem wykonuje
as String
sprawę.źródło
Jeśli pojawi się ostrzeżenie „zawsze prawdziwe / nieudane”, może być konieczne użycie opcji Any przed użyciem
is
źródło
źródło