31185


ExpressibleByBooleanLiteralプロトコルを適合した型で、  
if文でその変数の状態だけで、判断してほしいのですができません。  
if g {}が可能になるにはどうしたらよいでしょうか？

enum Grade : ExpressibleByBooleanLiteral{  
case A,B,C,D,E

[code]

    var boolValue : Bool{
        switch self{
            case .A,.B,.C:
                return true
            default:
                return false
        }
    }
    init(booleanLiteral value: Bool){
        if value{
            self = .A    
        }else{
            self = .E
        }
    
    }
    
[/code]

}

var g = Grade.A

if g {//コンパイルが通らない！！  
print("合格")  
}


CC BY-SA 3.0
2016-12-16T06:50:55.637
31182
2016-12-16T07:52:04.553
11148
question
swift
ExpressibleByBooleanLiteralの実装について


結論から言うと`ExpressibleByBooleanLiteral`は異なる目的のためのプロトコルで、あなたが所望の動作を行うためのプロトコルはSwift
3で廃止されました。

* * *

`ExpressibleByBooleanLiteral`と言うのはSwiftのboolean
literal(`true`または`false`のみ)を自身のデータ型として扱えるようにするためのプロトコルです。

`ExpressibleByBooleanLiteral`に適合させた型に対してはこんな書き方ができるようになります:

[code]

    //`Grade`型の変数に`true`や`false`を代入したり
    let g: Grade = true //(この例は本当は代入ではなく、宣言の初期化だが本当の代入もできる)
    func someFunc(grade: Grade) {
        print(grade)
    }
    //`Grade`型のパラメータに`true`や`false`を渡したり
    someFunc(grade: false) //->E
    
[/code]

* * *

あなたがご所望の機能(`if`の条件部など`Bool`型が必要な場所で明示的な型変換を書かなくても、`Bool`型の値に変換してくれる)は、古いSwiftで`BooleanType`とか`Boolean`とか呼ばれていたもの(Swiftのバージョンによりコロコロと名前が変わっています)ですが、Swift
3で正式に廃止されました。

[Xcode Release
Notes](https://developer.apple.com/library/content/releasenotes/DeveloperTools/RN-
Xcode/Introduction.html#//apple_ref/doc/uid/TP40001051)中の **Xcode 8.0**
内の[Swift](https://developer.apple.com/library/content/releasenotes/DeveloperTools/RN-
Xcode/Introduction.html#//apple_ref/doc/uid/TP40001051-CH1-SW146)の項目内を探すと("Boolean"あたりで検索してみてください)、次の素っ気ない1行が見つかります。

>   * The Boolean protocol has been removed.
> ([SE-0109](https://github.com/apple/swift-
> evolution/blob/master/proposals/0109-remove-boolean.md))
>

SE-0109と言うのはswift.org内のSwift Evolution(Swiftの進化)での公式提案の一つですが、 **Introduction**
のところを要約すると:

> `Bool`と`Boolean`なんて初心者にはややこしいだけだし、元々Objective-
> Cの`BOOL`をうまくSwift側にブリッジするために考えたんだけど今は`BOOL`はほとんど完璧に`Bool`にブリッジされちゃうし、そもそも標準ライブラリの中でも一貫した使われ方してないし(…だからもうそんなもの要らないよね。)

* * *

と言うわけで今更何かの役に立つというわけではないですが(Appleは「Swift2をサポートするのはXcode8.2が最後だから、さっさとSwift3に移行しろ」としつこくアナウンスしています)、Swift
2の時代にはこんな書き方ができたというのを紹介しておきます。(Xcode 8.2でもLegacy
Swiftの設定をYESにしたプロジェクトを作れば試せます。)

[code]

    enum Grade : BooleanType {
        case A,B,C,D,E
    
        var boolValue : Bool {
            switch self {
            case .A,.B,.C:
                return true
            default:
                return false
            }
        }
    }
    
    var g = Grade.A
    
    if g {
        print("合格") //->合格
    }
    
[/code]

* * *

Swift 3の場合、あきらめて

[code]

    if g.boolValue {
        print("合格") //->合格
    }
    
[/code]

と書くか、逆にもっと中身を表すわかりやすい名前をつけて、そちらの方を使うと言うのが(Swift開発チームの考える)正しい使い方と言うことになるのでしょう。

[code]

    enum Grade {
        case A,B,C,D,E
    
        //合格ならtrue
        var passes : Bool {
            switch self {
            case .A,.B,.C:
                return true
            default:
                return false
            }
        }
    }
    
    var g = Grade.A
    
    if g.passes {
        print("合格") //->合格
    }
    
[/code]


CC BY-SA 3.0
2016-12-16T07:52:04.553
31185
2016-12-16T07:52:04.553
13972
31182
answer