Swiftはじめたい...その１６ as is ?


# as とか is ってなんでしょ？as isじゃ現品って意味ですね。

+ だんだん独特な感じになってきましたね。下を参考にしました。
+ [Type Casting : The Swift Programming Language (Swift 2.1)](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/TypeCasting.html)

## is : 型チェック

+ オブジェクトの型がなにか？を調べられるらしいです。

```swift:isを試す。
protocol MyName {
    func myname()->String
}

class ClassA : MyName  {
    func myname()->String {
        return "I am A Type !"
    }
}

class ClassB : MyName {
    func myname()->String {
        return "I am B Type !"
    }
}

var arr:[MyName] = [ClassA(),ClassB()]

for var s in arr {
    print("ClassA Type ? \(s is ClassA)")
    print("ClassB Type ? \(s is ClassB)")
    print(s.myname())
    print("\n")
}
```

```shell:結果
ClassA Type ? true
ClassB Type ? false
I am A Type !


ClassA Type ? false
ClassB Type ? true
I am B Type !
```

+ まぁその通りだね、…な感じです。

+ でも〜〜、dynamicTypeでクラス名を文字列にしても似たようなことできそうですが駄目なのかな？

```swift:dynamicType
for var s in arr {
    switch String(s.dynamicType) {
    case "ClassA":
        print("A Type")
    case "ClassB":
        print("B Type")
    default:
        print("Other Type")
    }
    print(s.myname())
    print("\n")
}
```

## as : ダウンキャストする。

+ 型変換のキャストじゃなくてダウンキャストということらしいです。
+ ```[Intのオブジェクト] as String```的なことはできないようです。

```swift:downcast
let i = 1
print(i) // 1
print(i.dynamicType) // Int
let f = 1 as Float
print(f) // 1.0
print(f.dynamicType) // Float
```

+ これだとダウンキャストかキャストかよくわかりませんね。

### 継承したクラスで試してみます。

```swift:だから？
class Human {
}

class Man : Human  {
}

var human : Human = Man()

// let man1 = human as Man // エラーになります。
// error: 'Human' is not convertible to 'Man'; did you mean to use 'as!' to force downcast?

let man2 = human as! Man
let man3 = human as? Man

print(man2) // Man
print(man3) // Optional(Man)
```
+ これだと、だから何なの？って感じですね。

### JSONで試してみます。（配列）

+ JSONみたいに何が入ってくるかわからないのに有効なんじゃないでしょうか？

```swift:配列型のJSONをキャストする
import Foundation

let json_string = "[{\"a\":1,\"b\":\"str1\"},{\"a\":2,\"b\":\"str2\"}]"
let data = json_string.dataUsingEncoding(NSUTF8StringEncoding)

let obj = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers)
print("## as 無指定")
print(obj)
print("json[0].b -> \(obj[0]["b"]!!)")

let arr = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as? NSArray
print("\n## as? NSArray")
print(arr)
print("json[0].b -> \(arr![0]["b"]!!)")

let dic = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as? NSDictionary
print("\n## as? NSDictionary")
print(dic)

let arrdic = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as? [NSDictionary]
print("\n## as? [NSDictionary]")
print(arrdic)
print("json[0].b -> \(arrdic![0]["b"]!)")
```

```shell:結果
## as 無指定
(
        {
        a = 1;
        b = str1;
    },
        {
        a = 2;
        b = str2;
    }
)
json[0].b -> str1

## as? NSArray
Optional((
        {
        a = 1;
        b = str1;
    },
        {
        a = 2;
        b = str2;
    }
))
json[0].b -> str1

## as? NSDictionary
nil

## as? [NSDictionary]
Optional([{
    a = 1;
    b = str1;
}, {
    a = 2;
    b = str2;
}])
```

+ 元はArrayなのにDictionaryでダウンキャストしようとするとnilになりました。if let = 〜 で判定するといいかも？
+ 値を取ろうとしたら!!が必要になりました。なんでだろ？

### JSONで試してみます。（辞書）

+ 今度はいきなり辞書型をハンドリングしてみます。

```swift:辞書型のJSONをキャストする
let json_string = "{\"a\":1,\"b\":\"str1\"}"
let data = json_string.dataUsingEncoding(NSUTF8StringEncoding)

let obj = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers)
print("## as 無指定")
print(obj)
print("json.b -> \(obj["b"]!!)")

let arr = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as? NSArray
print("\n## as? NSArray")
print(arr)

let dic = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as? NSDictionary
print("\n## as? NSDictionary")
print(dic)
print("json.b -> \(dic!["b"]!)")
```

```shell:結果
## as 無指定
{
    a = 1;
    b = str1;
}
json.b -> str1

## as? NSArray
nil

## as? NSDictionary
Optional({
    a = 1;
    b = str1;
})
json.b -> str1
```

+ こっちも値を取ろうとしたら!!が必要になりました。

## まとめ

+ 自分で作るプログラムでは使わなそう…
+ CocoaでCF〜〜やら、NS〜〜やらをswiftの型に変換するときに使う時くらいなのかな？
+ きちんとキャストすると速度に効いてくるのかも？