文書   >   Swift   >   Swift 標準ライブラリ   >   Debugging and Reflection (デバッグと反映)   >   type(of:)


汎用関数


type(of:)


値の動的型を返します。





宣言


func type<T, Metatype>(of value: T) -> Metatype


パラメータ


value動的型を見つけるべき値。


戻り値


動的型。これはメタタイプのインスタンスです。


議論


type(of:) 関数を使用して、特に動的型が静的型と異なる場合に、値の動的型を見つけることができます。値の 静的型 は、既知のコンパイル時の値の型です。値の 動的型 は、実行時の値の実際の型であり、具体的な型のサブタイプになる場合があります。


以下のコードでは、count 変数は同じ静的型と動的型持っています:Int。ただし、countprintInfo(_:) 関数に渡されると、value パラメータの静的型は Any (パラメータに対して宣言された型) と動的型の Int になります。


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

let count: Int = 5
printInfo(count)
// '5' of type 'Int'


type(of:) から返される動的型は、クラス、構造体、列挙型、または他のプロトコルでない型 T の 具象メタタイプ (T.Type)、またはプロトコルまたはプロトコル構成 P実在メタタイプ (P.Type) です。type(of:) に渡される値の静的型がクラスまたはプロトコルに制限されている場合、そのメタタイプを使用して、イニシャライザまたはクラスまたはプロトコルの他の静的メンバーにアクセスできます。


たとえば、以下の例の printSmileyInfo(_:) 関数に value として渡されるパラメータは、Smiley クラスまたはそのサブクラスの 1 つのインスタンスです。この関数は type(of:) を使用して、value の動的型を検索しますが、value それ自体は Smiley.Type メタタイプのインスタンスです。


class Smiley {
    class var text: String {
        return ":)"
    }
}

class EmojiSmiley : Smiley {
     override class var text: String {
        return "😀"
    }
}

func printSmileyInfo(_ value: Smiley) {
    let smileyType = type(of: value)
    print("Smile!", smileyType.text)
}

let emojiSmiley = EmojiSmiley()
printSmileyInfo(emojiSmiley)
// Smile! 😀


この例では、smileyType メタタイプの text プロパティにアクセスすると、Smiley クラスの元の定義ではなく、EmojiSmiley サブクラスからオーバーライドされた値が取得されます。


汎用コンテキストでの動的型の検索


通常、具象メタタイプと実存メタタイプの違いを意識する必要はありませんが、type(of:) を呼び出すと、プロトコルに型パラメータが結束された汎用コンテキストで予期しない結果が生じる可能性があります。汎用パラメータ T がプロトコル P に結束されているこのような場合、型パラメータは汎用関数の本体のプロトコル型であるとは静的に認識されません。その結果、type(of:) は具象メタタイプ P.Protocol のみを生成できます。


以下の例では、汎用パラメータを受け取り、String 型の新しいプロトコル P への準拠を宣言する printGenericInfo(_:) 関数を定義しています。printGenericInfo(_:) がその静的型として P を含む文字列で呼び出されると、type(of:) への呼び出しは String.self(パラメータ内の動的型) ではなく P.self を返します。


func printGenericInfo<T>(_ value: T) {
    let t = type(of: value)
    print("'\(value)' of type '\(t)'")
}

protocol P {}
extension String: P {}

let stringAsP: P = "Hello!"
printGenericInfo(stringAsP)
// 'Hello!' of type 'P'


この予期しない結果は、printGenericInfo(_:) 内の type(of:value) への呼び出しが T.Type のインスタンスであるメタタイプを返さなければならないが、String.self (予想される動的型) は P.Type (value の具体的なメタタイプ) のインスタンスではありません。この汎用コンテキストでの value 内の動的な型を取得するには、type(of:) を呼び出すときにパラメータを Any にキャストして下さい。


func betterPrintGenericInfo<T>(_ value: T) {
    let t = type(of: value as Any)
    print("'\(value)' of type '\(t)'")
}

betterPrintGenericInfo(stringAsP)
// 'Hello!' of type 'String'


以下も見よ





実行時の値の照会

















トップへ












トップへ












トップへ












トップへ












トップへ
目次
Xcode の新機能

  • 言語:Swift
  • SDK


    Xcode 9.0+

    フレームワーク

    Swift 標準ライブラリ

  • 宣言
  • パラメータ
  • 戻り値
  • 議論
  • 以下も見よ












  • トップへ(Swift 標準ライブラリ)












    トップへ(Swift 標準ライブラリ)












    トップへ(Swift 標準ライブラリ)












    トップへ(Swift 標準ライブラリ)












    トップへ(Swift 標準ライブラリ)












    トップへ(Swift 標準ライブラリ)