書いて覚えるSwift入門
第41回 Swiftyなデータ処理
swift-sion
前回予告どおり,
to type or not to type, that's the question.
前回記事より,
- Swift:swift-sion by dankogai
- Go:go-sion by mattn
- ECMAScript
(aka JavaScript):js-sion by dankogai - Rust:sion-rs by pandaman64
- Python 3:py-sion by kamimura
ここで言う
何のためにシリアライズするのか
たとえばSIONのDictionary
。js-sionでは,String:SION
の場合はObject
,Map
にデシリアライズされます。どちらもECMAScript 6には標準装備されている型です。それに対し,
一見,eval()
でなされました。今ではJSON.
という専用関数が組み込まれましたが,Array
なりObject
なり,
しかし,Bool
に相当する型が不在で,0
ならfalse
,true
という扱いです。これがPerlになると0 but true
などという場合が出てきてさらにややこしい。こうした問題をどう解決するか。
必要は発明の母
「なければ作ればいい」。これは型にも当てはまります。Perlに標準装備のJSON::PP
では,JSON::PP::Boolean
という型―Perlにおいてはクラス―を用意してこの問題を解決しています。ただし用意されているのはあくまでもJSON
を表現するのに足りないデータ型だけで,JSON
型というのは用意されていません。これはある意味当然で,
use JSON::PP;
my $array_ref = json_decode('[0,1]');
my $hash_ref = json_decode('{"one":1}')
の$array_
は普通の配列リファレンス,$hash_
は普通のハッシュJSON::PP::Boolean
はある意味必要悪であり,"" . decode_
は"1"
となります。
シリアライズする2つの理由
それでは,SION
型を用意したのでしょう。JSON同様,
理由は2つ。1つはSwiftにeval()
が存在しないこと。同様のことは不可能ではありませんが,swiftc
が必要になります。これはSwiftが根底で
もう1つは,ExpressiveBy*Literal
プロトコル……,SION
型が成立するのです。
import SION
御託はこれくらいにして,README.
どおりに環境を整えたら,
import SION
とするだけです。これだけで,
var sion:SION = [
"nil": nil,
"bool": true,
"int": -42,
"double": 42.195,
"string": "漢字,カタカナ,ひらがなの入った
string",
"array": [nil, true, 1, 1.0, "one", [1],
["one":1.0]],
"dictionary": [
"nil":nil, "bool":false, "int":0, "double":0.0, "string":"","array":[], "object":[:]
],
"url":"https://github.com/dankogai/"
]
という具合にふつうにSIONをリテラルとして受け付けます。試しに:SION
を取ってみてください。どうなりましたか?
もちろん,
SION(string:sionStr)
SION(json:jsonStr)
SION(jsonUrlString:"https://api.github.com")
SION(propertyList:plistXML.data(using:.utf8)!, format:.xml)
SION(msgPack:msgData)
デシリアライゼーションはさらに簡単で,sion.
でも"\(sion)"
でもいいですし,print(sion)
してもいいでしょう。
直感的なのは,
var sa = SION([])
で,
sa[0] = nil
sa[1] = true
sa[2] = 1
という具合にあたかも組込みの配列のように値を代入できますし,
var sd = SION([:])
sd["nil"] = nil
sd["bool"] = false
sd["int"] = 0
とできます。1点Array
では範囲外へのアクセスはfatalError
になりますし,Dictionary
で存在しないキーはnil
を返しますが,.Error()
という特別な値を用意し,
もう1点注意を要するのは,
sa[1] = true // SION.Bool(true)
sa[2] = 1 // SION.Int(1)
であり,
sa[1].bool
sa[2].int
とします。なおこれらのコンピューテッド・
sion[2].int! += 1 // now 2
sion[3].double! *= 0.5 // now 0.5
sion[4].string!.removeLast() // now "on"
sion[5].array!.append(2) // now [1, 2]
sion[6].dictionary!["two"] = 2 // now
["one":1,"two":2]
次回予告
swift-sionやSwiftyJSONのような
本誌最新号をチェック!
Software Design 2019年3月号
2019年2月18日発売
B5判/184ページ
定価(本体1,220円+税)
- 第1特集
ITエンジニアのための機械学習と微分積分入門
基礎としくみを押さえて理解を促進 - 第2特集
Webに携わるエンジニアの必須科目
ベーシックなJavaScriptをちゃんと身につけよう - 短期連載
サーバサイド開発の品質を向上させるJava→Kotlin移行のススメ
【2】Javaのフレームワークを使い手軽にKotlin開発を始める - 短期連載
StrutsからSpringへの移行実践ノウハウ
【1】フレームワークの歴史と技術的負債