web-dev-qa-db-ja.com

NSLogを使用したSwift enumのロギング

列挙型を記録しようとしています:

enum CKAccountStatus : Int {
    case CouldNotDetermine
    case Available
    case Restricted
    case NoAccount
}

NSLog("%i", CKAccountStatus.Available)

コンパイラは文句を言う:

Type 'CKAccountStatus' does not conform to protocol 'CVarArg'

どうして?私は値をキャストしようとしました:

NSLog("%i", CKAccountStatus.Available as Int)

しかし、それでも問題はありません。

Cannot convert the expression's type '()' to type 'String'
22
zoul

列挙型の基礎となるInt値:CKAccountStatus.Available.rawValueを取得します。

EnumはSwiftでは厳密には整数ではありませんが、基礎となる型で宣言されている場合は、rawValueを使用して取得できます。 (enum Foo: Stringは、rawValueなどの文字列を提供します。)enumに基礎となる型がない場合、rawValueは何も提供しません。 ObjCからインポートされたAPIでは、NS_ENUMで定義されたすべての列挙型には、基になる整数型(通常はInt)があります。

Enumをより説明的に印刷したい場合は、Printableプロトコルを採用するenum型に拡張を行うことを検討してください。

28
rickster

列挙型は事実上不透明です。取得できる生の値がある場合があります。しかし、多くの列挙型はサポートしていません。 (列挙型を型として宣言する必要はありません。宣言しない場合、生の値はありません。)私が行うことは、列挙型にdescriptionメソッドを指定し、それを明示的に呼び出すことです。

Enumの現在の値を区別する唯一の方法は、switchステートメントを使用することです。そのため、descriptionメソッドは各ケースを処理し、switchステートメントの各ケースは異なる説明的な値を返します。

enum Suit {
    case Hearts, Diamonds, Spades, Clubs
    func description () -> String {
        switch self {
        case Hearts:
            return "hearts"
        case Diamonds:
            return "diamonds"
        case Spades:
            return "spades"
        case Clubs:
            return "clubs"
        }
    }
}

var suit = Suit.Diamonds
println("suit \(suit.description())")  // suit diamonds
8
matt

これは私のアプローチです:

enum UserMode : String
{
   case Hold = "Hold";
   case Selecting = "Selecting";
   case Dragging = "Dragging";
}

次に、生の値を出力する必要があるときはいつでも:

//Assuming I have this declared and set somewhere
var currentMode: UserMode = .Selecting;

している

NSLog("CurrentMode \(_currMode.rawValue)");

印刷されます:

CurrentModeの選択

5
Chris Amelinckx

Swift docsから:

Cに精通している場合は、C列挙型が整数値のセットに関連する名前を割り当てることがわかります。 Swiftの列挙型はより柔軟であり、列挙型の各メンバーに値を提供する必要はありません。値(「生の」値と呼ばれる)が各列挙型メンバーに提供されている場合、値は文字列、文字、または任意の整数型または浮動小数点型の値にすることができます。

したがって、それをIntにキャストすることはできません。最初の問題に関する限り、NSLog()はC変数タイプのパラメーターを探しているようです。これはSwift enumsには適用されません)。

1
67cherries

私が使用するエラー列挙型には

public var localizedDescription : String { return String(reflecting: self) }

他の列挙型の場合、次のように使用できるCustomStringConvertibleプロトコルがあります

public var description : String { return String(reflecting: self) }
0
JMiguel

ええ、列挙型はSwiftの数値ではありません。

CやObjective-Cとは異なり、Swift列挙型メンバーには、作成時にデフォルトの整数値が割り当てられません。上のCompassPointsの例では、North、South、East、Westは暗黙的に0に等しくありません。 1、2、3。代わりに、さまざまな列挙型メンバーは、明示的に定義されたタイプのCompassPointを備えた、それ自体が完全に本格的な値です。

値を簡単に記録する方法はありますか?ああ、あります:

NSLog("%i", CKAccountStatus.Available.toRaw())
0
zoul

次のように、toRaw()関数を使用して、enumのInt-Valueを取得できます。

import Foundation

enum CKAccountStatus : Int {
    case CouldNotDetermine
    case Available
    case Restricted
    case NoAccount
}

let block = {(status: Int) -> Void in
    NSLog("%d", status)
}

let status = CKAccountStatus.Available.toRaw()
block(status) // prints "1"
0
wottpal