Swift'te bir değişkenin türünü veya sınıfını nasıl yazdırabilirim?


335

Bir değişkenin çalışma zamanı türünü hızlı bir şekilde yazdırmanın bir yolu var mı? Örneğin:

var now = NSDate()
var soon = now.dateByAddingTimeInterval(5.0)

println("\(now.dynamicType)") 
// Prints "(Metatype)"

println("\(now.dynamicType.description()")
// Prints "__NSDate" since objective-c Class objects have a "description" selector

println("\(soon.dynamicType.description()")
// Compile-time error since ImplicitlyUnwrappedOptional<NSDate> has no "description" method

Yukarıdaki örnekte, "yakında" değişkeninin tür ImplicitlyUnwrappedOptional<NSDate>veya en azından olduğunu göstermenin bir yolunu arıyorum NSDate!.


43
@JasonMArcher Bağladığınız soru bundan 4 gün sonra sorulursa bunun nasıl bir kopya olduğunu söyle?
akashivskyy

Bir Swift nesnesinin türünü test etme veya bir Swift nesnesinin türünü okuma hakkında birkaç soru vardır. Biz sadece bu konuda "usta" sorular olarak kullanmak için en iyi soruları bulmak. Önerilen kopya çok daha kapsamlı bir cevaba sahiptir. Bu yanlış bir şey yaptığınızı söylemek değil, sadece dağınıklığı azaltmaya çalışıyoruz.
JasonMArcher

4
Önerilen kopya aynı soruyu cevaplamıyor; Type.self, hata ayıklama amacıyla konsola yazdırılamaz, Türleri nesne olarak alan diğer işlevlere geçmek için kullanılır.
Matt Bridges

2
OT: Swift'in kutudan çıkmadığını sunması çok garip ve bu tür düşük seviyeli C kütüphaneleriyle uğraşmak gerekiyor. Hata raporuna değer mi?
qwerty_so

Çocuklar, cevabımı aşağıda verdim. Lütfen bir göz atın ve beklenen şey olup olmadığını bana bildirin.
DILIP KOSURI

Yanıtlar:


377

Eylül 2016 Güncellemesi

Swift 3.0: Kullanım type(of:), ör. type(of: someThing)( dynamicTypeAnahtar kelime kaldırıldığı için)

Ekim 2015 güncellemesi :

Ben (örneğin yeni Swift 2.0 sözdizimi için aşağıdaki örnekleri güncellenmiş printlnile değiştirildi print, toString()şimdiString() ).

Xcode 6.3 sürüm notlarından :

@nschum, Xcode 6.3 sürüm notlarının başka bir yol gösterdiğini belirtiyor :

Yazım değerleri artık println veya string enterpolasyonu ile birlikte kullanıldığında tam demonte yazım adı olarak yazdırılır.

import Foundation

class PureSwiftClass { }

var myvar0 = NSString() // Objective-C class
var myvar1 = PureSwiftClass()
var myvar2 = 42
var myvar3 = "Hans"

print( "String(myvar0.dynamicType) -> \(myvar0.dynamicType)")
print( "String(myvar1.dynamicType) -> \(myvar1.dynamicType)")
print( "String(myvar2.dynamicType) -> \(myvar2.dynamicType)")
print( "String(myvar3.dynamicType) -> \(myvar3.dynamicType)")

print( "String(Int.self)           -> \(Int.self)")
print( "String((Int?).self         -> \((Int?).self)")
print( "String(NSString.self)      -> \(NSString.self)")
print( "String(Array<String>.self) -> \(Array<String>.self)")

Hangi çıktılar:

String(myvar0.dynamicType) -> __NSCFConstantString
String(myvar1.dynamicType) -> PureSwiftClass
String(myvar2.dynamicType) -> Int
String(myvar3.dynamicType) -> String
String(Int.self)           -> Int
String((Int?).self         -> Optional<Int>
String(NSString.self)      -> NSString
String(Array<String>.self) -> Array<String>

Xcode 6.3 Güncellemesi:

Şunları kullanabilirsiniz _stdlib_getDemangledTypeName():

print( "TypeName0 = \(_stdlib_getDemangledTypeName(myvar0))")
print( "TypeName1 = \(_stdlib_getDemangledTypeName(myvar1))")
print( "TypeName2 = \(_stdlib_getDemangledTypeName(myvar2))")
print( "TypeName3 = \(_stdlib_getDemangledTypeName(myvar3))")

ve bunu çıktı olarak alın:

TypeName0 = NSString
TypeName1 = __lldb_expr_26.PureSwiftClass
TypeName2 = Swift.Int
TypeName3 = Swift.String

Orijinal cevap:

Xcode 6.3'ten önce _stdlib_getTypeNamebir değişkenin karıştırılmış tip adını aldı. Ewan Swick tarafından yazılmış blog yazısı şu dizeleri deşifre etmeye yardımcı olur:

örneğin _TtSiSwift'in dahiliInt türü .

Mike Ash, aynı konuyu kapsayan harika bir blog girişine sahip .


2
Nasıl buldun _stdlib_getTypeName()? Entegre REPL artık mevcut swift-ide-testdeğil, mevcut da değil ve _Xcode'un Swift modülünü yazdırması önceden düzeltilmiş değerleri kullanıyor.
Lily Ballard

10
Görünüşe göre lldbkolayca yeterince simgeleri ile arama yapabilirsiniz . Ayrıca var _stdlib_getDemangledTypeName()ve _stdlib_demangleName().
Lily Ballard

1
Ah düzgün, bunun imageiçin bir kısayol olduğunu fark etmedim target modules. target modules lookup -r -n _stdlib_Tabii ki daha iyi ifade edilen kullanarak sona erdiimage lookup -r -n _stdlib_ libswiftCore.dylib
Lily Ballard

1
FYI - Görünüşe göre toString (...), String (...) ile değiştirildi.
Nick

6
Swift 3.0: dynamicTypeAnahtar kelime Swift'ten kaldırıldı. Onun yerine type(of:)dile yeni bir ilkel işlev eklendi: github.com/apple/swift/blob/master/CHANGELOG.md
Szu

46

Düzenleme: Swift 1.2'de (Xcode 6.3) yeni bir toStringişlev getirildi .

Artık herhangi bir türün demonte edilmiş türünü .selfve herhangi bir örneği aşağıdakileri kullanarak yazdırabilirsiniz .dynamicType:

struct Box<T> {}

toString("foo".dynamicType)            // Swift.String
toString([1, 23, 456].dynamicType)     // Swift.Array<Swift.Int>
toString((7 as NSNumber).dynamicType)  // __NSCFNumber

toString((Bool?).self)                 // Swift.Optional<Swift.Bool>
toString(Box<SinkOf<Character>>.self)  // __lldb_expr_1.Box<Swift.SinkOf<Swift.Character>>
toString(NSStream.self)                // NSStream

Aramayı deneyin YourClass.selfve yourObject.dynamicType.

Referans: https://devforums.apple.com/thread/227425 .


2
Bu konuya cevap verdim ama yorumumu buraya ekleyeceğim. Bu değerler "Metatip" türündedir, ancak bir Metatip nesnesinin hangi türü temsil ettiğini bulmanın kolay bir yolu yoktur, aradığım şey budur.
Matt Bridges

Metatip türündeler ve sınıflar. Bir sınıfı temsil ederler. Sorununuzun tam olarak ne olduğundan emin değilim. someInstance.dynamicType.printClassName()sınıfın adını yazdırır.
Analog Dosya

18
printClassName () yöntemi yalnızca dokümanlardaki örneklerden birinde oluşturdukları örnek bir yöntemdir, erişebileceğiniz bir API çağrısı değildir.
Dave Wood

4
Görünen o ki, String (...)
Nick

33

Swift 3.0

let string = "Hello"
let stringArray = ["one", "two"]
let dictionary = ["key": 2]

print(type(of: string)) // "String"

// Get type name as a string
String(describing: type(of: string)) // "String"
String(describing: type(of: stringArray)) // "Array<String>"
String(describing: type(of: dictionary)) // "Dictionary<String, Int>"

// Get full type as a string
String(reflecting: type(of: string)) // "Swift.String"
String(reflecting: type(of: stringArray)) // "Swift.Array<Swift.String>"
String(reflecting: type(of: dictionary)) // "Swift.Dictionary<Swift.String, Swift.Int>"

1
Swift 2 uygulaması, enum vakalarında özellikle iyi. Bu davranışın Apple tarafından belgelenip belgelenmediğini / garanti edildiğini bilen var mı? Standart kütüphane sadece bu hata ayıklama için uygun bir yorum içerir ...
milos

30

Bu aradığınız şey mi?

println("\(object_getClassName(now))");

"__NSDate" yazdırır

GÜNCELLEME : Bunun Beta05'ten itibaren artık işe yaramadığını lütfen unutmayın


2
Hızlı sınıflar için çalışmaz. "UnsafePointer (0x7FBB18D06DE0)" döndürür
aryaxt

4
Bir NSManagedObject I için, (beta5 en azından) sadece "Builtin.RawPointer = adresi" objc sınıfları için değil işi ya olsun mu
Kendall Helmstetter Gelner

23

Geçerli Xcode'um Sürüm 6.0 (6A280e).

import Foundation

class Person { var name: String; init(name: String) { self.name = name }}
class Patient: Person {}
class Doctor: Person {}

var variables:[Any] = [
    5,
    7.5,
    true,
    "maple",
    Person(name:"Sarah"),
    Patient(name:"Pat"),
    Doctor(name:"Sandy")
]

for variable in variables {
    let typeLongName = _stdlib_getDemangledTypeName(variable)
    let tokens = split(typeLongName, { $0 == "." })
    if let typeName = tokens.last {
        println("Variable \(variable) is of Type \(typeName).")
    }
}

Çıktı:

Variable 5 is of Type Int.
Variable 7.5 is of Type Double.
Variable true is of Type Bool.
Variable maple is of Type String.
Variable Swift001.Person is of Type Person.
Variable Swift001.Patient is of Type Patient.
Variable Swift001.Doctor is of Type Doctor.

1
Güzel, ama aynı zamanda soru da dahil edildi Seçenek, seçeneklerin çıkışı ayarlanır Optional(...), bu nedenle kodunuz yalnızca OptionalTür olarak döner . Ayrıca var optionalTestVar: Person? = Person(name:"Sarah")İsteğe bağlı (Kişi) olarak göstermeli ve Kişi ile değişmelidir ! as ImplicitlyUnwrappedOptional (Person)
Binarian

18

Swift 1.2 ile Xcode 6.3'ten itibaren, tip değerlerini tam olarak demonte haline dönüştürebilirsiniz String.

toString(Int)                   // "Swift.Int"
toString(Int.Type)              // "Swift.Int.Type"
toString((10).dynamicType)      // "Swift.Int"
println(Bool.self)              // "Swift.Bool"
println([UTF8].self)            // "Swift.Array<Swift.UTF8>"
println((Int, String).self)     // "(Swift.Int, Swift.String)"
println((String?()).dynamicType)// "Swift.Optional<Swift.String>"
println(NSDate)                 // "NSDate"
println(NSDate.Type)            // "NSDate.Type"
println(WKWebView)              // "WKWebView"
toString(MyClass)               // "[Module Name].MyClass"
toString(MyClass().dynamicType) // "[Module Name].MyClass"

Diğer yön 1.2'de mümkün müdür? Sınıf adına göre bir örnek başlatmak için?
user965972

@ user965972 Bildiğim kadarıyla ben orada olduğunu sanmıyorum.
kiding

17

Yine de className(a döndüren String) sınıfa erişebilirsiniz .

Örneğin sınıf almak için çeşitli yollar, aslında vardır classForArchiver, classForCoder, classForKeyedArchiver(bütün dönüş AnyClass!).

Bir ilkel türünü alamazsınız (ilkel bir sınıf değildir ).

Misal:

var ivar = [:]
ivar.className // __NSDictionaryI

var i = 1
i.className // error: 'Int' does not have a member named 'className'

Bir ilkel türünü almak istiyorsanız, kullanmanız gerekir bridgeToObjectiveC(). Misal:

var i = 1
i.bridgeToObjectiveC().className // __NSCFNumber

Eminim ilkeldir. Ne yazık ki ilkel bir tür elde edemezsiniz.
Leandros

Bu örnekler oyun alanında işe yaramıyor gibi görünüyor. İlkel ve ilkel olmayanlar için hatayı alıyorum.
Matt Bridges

denemek import Cocoa.
Leandros

9
className, yalnızca OSX için geliştirirken NSObjects için kullanılabilir; iOS SDK'sında NSObjects veya "normal" nesneler için kullanılamaz
Matt Bridges

3
classNameCocoa'nın AppleScript desteğinin bir parçasıdır ve kesinlikle genel içgözlem için kullanılmamalıdır. Açıkçası iOS'ta mevcut değil.
Nikolai Ruhe

16

Nesne hakkında bilgi almak için yansıtma işlevini kullanabilirsiniz.
Örneğin nesne sınıfının adı:

var classname = yansıtmak (şimdi).

Beta 6'da, bu bana uygulama adını + sınıf adını hafifçe karıştırılmış bir biçimde aldı, ancak bu bir başlangıç. +1 için reflect(x).summary- teşekkürler!
Olie

işe yaramadı, Swift 1.2 Xcode 6.4 ve iOs 8.4'te boş bir satır yazdırıyor
Juan Boero

13

Şansım vardı:

let className = NSStringFromClass(obj.dynamicType)

@hdost dude hiçbir şey işe yaramadı ama classForCoder çalıştı.
Satheeshwaran

12

Xcode 8 Swift 3.0 kullanım türü (of :)

let className = "\(type(of: instance))"

10

Xcode 8'de Swift 3.0

Adımlar:

1. Türü Al:

Seçenek 1:

let type : Type = MyClass.self  //Determines Type from Class

Seçenek 2:

let type : Type = type(of:self) //Determines Type from self

2. Türü Dizeye Dönüştür:

let string : String = "\(type)" //String

8

Swift 3.0'da kullanabileceğiniz type(of:)gibi dynamicTypeanahtar kelime kaldırılmıştır.


7

SWIFT 5

Swift 3'ün en son sürümünde, Stringbaşlatıcı aracılığıyla tip adlarının güzel açıklamalarını alabiliriz . Mesela print(String(describing: type(of: object))). Dizi, sözlük, an , a , özel sınıf örneği vb. Gibi object bir örnek değişkeni nerede olabilir?IntNSDate

İşte tam cevabım: Swift'te nesnenin sınıf adını dize olarak alın

Bu soru bir nesnenin sınıf adını dize olarak almak için bir yol arıyor, ama ben de alt sınıf olmayan bir değişkenin sınıf adını almak için başka bir yol önerdi NSObject. İşte burada:

class Utility{
    class func classNameAsString(obj: Any) -> String {
        //prints more readable results for dictionaries, arrays, Int, etc
        return String(describing: type(of: obj))
    }
}

Parametre olarak tür bir nesne alır Anyve kendi sınıf adını döndürür statik bir işlev yaptıString :) .

Bu işlevi gibi bazı değişkenlerle test ettim:

    let diccionary: [String: CGFloat] = [:]
    let array: [Int] = []
    let numInt = 9
    let numFloat: CGFloat = 3.0
    let numDouble: Double = 1.0
    let classOne = ClassOne()
    let classTwo: ClassTwo? = ClassTwo()
    let now = NSDate()
    let lbl = UILabel()

ve çıktı:

  • diccionary türündedir Sözlük
  • dizi Array türündedir
  • numInt Int türündedir
  • numFloat, CGFloat tipindedir
  • numDouble çift tiptedir
  • classOne türü: ClassOne
  • classTwo türü: ClassTwo
  • şimdi türü: Tarih
  • lbl türü: UILabel

5

Kakao kullanırken (CocoaTouch değil), classNameözelliği NSObject öğesinin alt sınıfı olan nesneler için kullanabilirsiniz .

println(now.className)

Bu özellik, NSObject öğesinin alt sınıfı olmayan normal Swift nesneleri için kullanılamaz (ve aslında Swift'te kök kimliği veya nesne türü yoktur).

class Person {
    var name: String?
}

var p = Person()
println(person.className) // <- Compiler error

CocoaTouch'da, şu anda belirli bir değişkenin türünün dize açıklamasını almanın bir yolu yoktur. Benzer işlevsellik, Kakao veya CocoaTouch'daki ilkel tipler için de mevcut değildir.

Swift REPL, türü de dahil olmak üzere değerlerin bir özetini yazdırabilir, bu nedenle bu içgözlemin gelecekte bir API aracılığıyla mümkün olması mümkündür.

EDIT : dump(object)hile gibi görünüyor.


Xcode 10 ve Swift 4.2'den itibaren bile dump(object)gerçekten güçlü. Teşekkür ederim.
Alex Zavatone

5

En iyi yanıt, bunu kullanarak yeni bir yolun çalışan bir örneğine sahip değildir type(of:. Benim gibi çaylaklara yardımcı olmak için, burada çoğunlukla Apple'ın dokümanlarından alınan çalışan bir örnek var - https://developer.apple.com/documentation/swift/2885064-type

doubleNum = 30.1

func printInfo(_ value: Any) {
    let varType = type(of: value)
    print("'\(value)' of type '\(varType)'")
}

printInfo(doubleNum)
//'30.1' of type 'Double'

4

Burada diğer cevapların bazılarını denedim ama milaj altta yatan nesnenin ne olduğu çok görünüyor.

Ancak aşağıdakileri yaparak bir nesne için Object-C sınıf adını alabilirsiniz bir yol buldum:

now?.superclass as AnyObject! //replace now with the object you are trying to get the class name for

İşte ve nasıl kullanacağınıza dair örnek:

let now = NSDate()
println("what is this = \(now?.superclass as AnyObject!)")

Bu durumda NSDate'i konsolda yazdıracaktır.


4

Umarım başka biri için işe yarayabilir. Değere erişmek için bir sınıf yöntemi oluşturdum. Lütfen bunun yalnızca NSObject alt sınıfı için çalışacağını unutmayın. Ama en azından temiz ve düzenli bir çözüm.

class var className: String!{
    let classString : String = NSStringFromClass(self.classForCoder())
    return classString.componentsSeparatedByString(".").last;
}

4

Swift 1.2 ile en son XCode 6.3'te bulduğum tek yol bu:

if view.classForCoder.description() == "UISegment" {
    ...
}

NOT: description (), sınıf adını biçiminde döndürür <swift module name>.<actual class name>, böylece dizeyi a ile bölmek .ve son simgeyi almak istersiniz .
Matthew Quiros

4

Buradaki cevapların çoğu en son Swift ile çalışmaz (Xcode 7.1.1 yazma sırasında).

Bilgiyi elde etmenin şu andaki yolu, bunu oluşturmak Mirrorve sorgulamaktır. Sınıf adı için bu kadar basit:

let mirror = Mirror(reflecting: instanceToInspect)
let classname:String = mirror.description

Nesne hakkında ek bilgi de adresinden alınabilir Mirror. Ayrıntılar için http://swiftdoc.org/v2.1/type/Mirror/ adresine bakın.


Stackoverflow.com/a/25345480/1187415 ve stackoverflow.com/a/32087449/1187415 yanıtlarının sorunu nedir? Her ikisi de Swift 2 ile oldukça iyi çalışıyor gibi görünüyor. (Diğerlerini kontrol etmedim.)
Martin R

Bunu genel bir çözüm olarak beğendim, ancak "Ayna için ViewController" (yabancı "Ayna için") almak - beklemek, ".subjectType" kullanarak hile yapar gibi görünüyor!
David H

3

Beta 5'ten itibaren lldb'de, bir nesnenin sınıfını şu komutla görebilirsiniz:

fr v -d r shipDate

hangi gibi bir çıktı üretir:

(DBSalesOrderShipDate_DBSalesOrderShipDate_ *) shipDate = 0x7f859940

Genişletilmiş komut şöyle bir şey anlamına gelir:

Frame Variable (çerçeve değişkeni yazdır) -d run_target (dinamik türleri genişlet)

Bilmenizde fayda olan bir şey, değişken değerlerin çıktısını almak için "Kare Değişkeni" kullanmanın hiçbir kod yürütülmediğini garanti etmesidir.


3

Kendi geliştirdiğim dersler için bir çözüm buldum (ya da erişebileceğin bir şey).

Aşağıdaki hesaplanan özelliği , nesnelerinizin sınıf tanımına yerleştirin:

var className: String? {
    return __FILE__.lastPathComponent.stringByDeletingPathExtension
}

Şimdi nesnenizdeki sınıf adını şöyle çağırabilirsiniz:

myObject.className

Bunun yalnızca sınıf tanımınızın tam olarak adlandırılmış bir dosyada yapılması durumunda işe yarayacağını unutmayın. istediğiniz sınıf gibi .

Bu genellikle olduğu gibi , yukarıdaki cevap çoğu durumda bunu yapmalıdır . Ancak bazı özel durumlarda farklı bir çözüm bulmanız gerekebilir.


Sınıf (dosya) içinde sınıf adına ihtiyacınız varsa, bu satırı kullanabilirsiniz:

let className = __FILE__.lastPathComponent.stringByDeletingPathExtension

Belki bu yöntem bazı insanlara yardım eder.


3

Yukarıdaki Klass ve Kevin Ballard tarafından verilen cevaplara ve yorumlara dayanarak, ben:

println(_stdlib_getDemangledTypeName(now).componentsSeparatedByString(".").last!)
println(_stdlib_getDemangledTypeName(soon).componentsSeparatedByString(".").last!)
println(_stdlib_getDemangledTypeName(soon?).componentsSeparatedByString(".").last!)
println(_stdlib_getDemangledTypeName(soon!).componentsSeparatedByString(".").last!)

println(_stdlib_getDemangledTypeName(myvar0).componentsSeparatedByString(".").last!)
println(_stdlib_getDemangledTypeName(myvar1).componentsSeparatedByString(".").last!)
println(_stdlib_getDemangledTypeName(myvar2).componentsSeparatedByString(".").last!)
println(_stdlib_getDemangledTypeName(myvar3).componentsSeparatedByString(".").last!)

yazdırılacak:

"NSDate"
"ImplicitlyUnwrappedOptional"
"Optional"
"NSDate"

"NSString"
"PureSwiftClass"
"Int"
"Double"

Bence bu daha iyi bir yanıt.
maschall

Swift 1.2'de şunları kullandım: toString(self.dynamicType).componentsSeparatedByString(".").last!Açıkçası bir nesne bağlamındaydım ve referans verebildim self.
Joe,

3
let i: Int = 20


  func getTypeName(v: Any) -> String {
    let fullName = _stdlib_demangleName(_stdlib_getTypeName(i))
    if let range = fullName.rangeOfString(".") {
        return fullName.substringFromIndex(range.endIndex)
    }
    return fullName
}

println("Var type is \(getTypeName(i)) = \(i)")

3

Swift sürüm 4:

print("\(type(of: self)) ,\(#function)")
// within a function of a class

Teşekkürler @Joshua Dance


3

Hızlı 4:

// "TypeName"
func stringType(of some: Any) -> String {
    let string = (some is Any.Type) ? String(describing: some) : String(describing: type(of: some))
    return string
}

// "ModuleName.TypeName"
func fullStringType(of some: Any) -> String {
    let string = (some is Any.Type) ? String(reflecting: some) : String(reflecting: type(of: some))
    return string
}

Kullanımı:

print(stringType(of: SomeClass()))     // "SomeClass"
print(stringType(of: SomeClass.self))  // "SomeClass"
print(stringType(of: String()))        // "String"
print(fullStringType(of: String()))    // "Swift.String"

2

Rasgele bir değerin türünün tür adını yazdırmanın genel bir yolu yok gibi görünüyor. Diğerlerinin de belirttiği gibi, sınıf örnekleri için yazdırabilirsinizvalue.className ancak ilkel değerler için çalışma zamanında tür bilgisinin gittiği görülür.

Örneğin, şunu yazmanın bir yolu yok gibi görünüyor: 1.something()ve Intherhangi bir değeri için dışarı çıkmak something. (Başka cevap önerildiği gibi Sen, kullanım olabilir i.bridgeToObjectiveC().classNamesize bir ipucu vermek, bunlarla __NSCFNumberolduğu değil aslında tipi i-. O bir Objective-C işlev çağrısı sınırdan geçer zaman dönüştürülecektir sadece ne)

Yanlış kanıtlanmış olmaktan mutluluk duyarız, ancak tür kontrolünün derleme zamanında yapıldığı ve C ++ (RTTI devre dışı bırakıldığında) gibi tür bilgilerinin çoğu çalışma zamanında gitti gibi görünüyor.


Xcode6'nın oyun alanında çalışan örneğimdeki "now" değişkeni için "NSDate" yazdırmak için className kullanma örneği verebilir misiniz? Anlayabildiğim kadarıyla className, Swift nesnelerinde, NSObject öğesinin alt sınıflarında bile tanımlanmamış.
Matt Bridges

Görünen o ki 'className' NSObject'ten gelen nesneler için kullanılabilir, ancak iOS için değil, yalnızca mac için geliştirirken. İOS için hiç geçici çözüm yok gibi görünüyor.
Matt Bridges

1
Evet, buradaki asıl paket, genel durumda, tür bilgisinin çalışma zamanında hızlı bir şekilde gittiğidir.
ipmcc

Yine de REPL'in değer türlerini nasıl yazdırabileceğini merak ediyorum.
Matt Bridges

REPL neredeyse kesinlikle yorumlanır ve derlenmez, bu kolayca açıklar
ipmcc

2

Bu, bir tür dizesi olsun nasıl nesne veya Tip olduğu tutarlı ve dikkate hangi alır modülü nesne tanımı aittir ya Swift 4.x'teki. İşlerin iç içe

@inline(__always) func typeString(for _type: Any.Type) -> String {
    return String(reflecting: type(of: _type))
}

@inline(__always) func typeString(for object: Any) -> String {
    return String(reflecting: type(of: type(of: object)))
}

struct Lol {
    struct Kek {}
}

// if you run this in playground the results will be something like
typeString(for: Lol.self)    //    __lldb_expr_74.Lol.Type
typeString(for: Lol())       //    __lldb_expr_74.Lol.Type
typeString(for: Lol.Kek.self)//    __lldb_expr_74.Lol.Kek.Type
typeString(for: Lol.Kek())   //    __lldb_expr_74.Lol.Kek.Type

2

Bir almak için nesnenin türünü veya nesnenin sınıfında yer Swift , bir kullanmak gerekir gereken türünü (bir: yourObject)

type (of: yourObject)


1

Tam olarak ne olduğunuzu değil, aynı zamanda Swift türlerine göre değişkenin türünü de kontrol edebilirsiniz:

let object: AnyObject = 1

if object is Int {
}
else if object is String {
}

Örneğin.


1

Xcode 7.3.1, Swift 2.2:

String(instanceToPrint.self).componentsSeparatedByString(".").last

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.