◆ Linux で使うものじゃない
◆ オープンにはしても Apple の OS 以外お断り感がでてる

前に書いたいろいろな言語の REPL で Swift だけ fedora だと大変で略してたので Ubuntu 系のディストリビューションでやって追記しました
せっかくあまり使わないディストリビューションの Linux を起動までして入れたのですし 1 + 1 だけで終わるのもなんかもったいない感があったので ついでにもうちょっとだけいじってみました

Objective-C の型はない

使ってみるとバージョンは合ってるのにあちこちで紹介されてる方法をそのままコピーしても動かないことが多発しました
公式のドキュメントも見ておこうと思ったのですが ググってもあまり上にいないし見づらいです
Qiita や Stackoverflow のほうが上に来るのも納得です

調べてみると Swift は昔の Mac 向けのプログラミング言語の Objective-C の機能 NS*** という型名も使えるようにされているようです
ですが それは Mac でのみで Linux に Swift を入れても Swift 自体の機能は動きますが Objective-C の機能は使えません

文字列だと String と NSString の 2 つが Swift では扱えて String のメソッド呼び出しで NSString のメソッドも使えるようです
NSString というのは Objective-C のものなので Linux で Swift を実行させるとこの型は見つからないと言われます

  1> let str:NSString = "a"
error: repl.swift:1:9: error: use of undeclared type 'NSString'
let str:NSString = "a"
^~~~~~~~

普通の String 型は問題ありません

  1> let str:String = "a"
str: String = "a"

最初は String 型だけでも問題ないのでは と思ってました
ですが 多くのページで紹介されている方法は基本 NSString のメソッドです
String 型はあんまり機能がなくて ほとんどを NSString に任せてるみたいです

とりあえず適当な文字列操作として正規表現置換や trim を調べてみたのですが どこを調べても出てくるのは

  • NSRegularExpression クラス
  • replacingOccurrences メソッド
  • trimmingCharacters メソッド

を使った方法です
どれも NS 系で Linux の Swift だと動きません

trim したい

じゃあ String で trim って無理なのかなと思ってしばらく調べていたのですが やっぱり全然方法が見当たりません
みんなが NSString 機能つかってるみたいです
まぁ Linux で使おうとする人は少ないと思いますけど
それでも 使える以上使ってる人はいると思いますし その人がなにか方法書いてそうなのに全然ありません
C 言語でだって正規表現を使って比較的楽に trim できるのに 今どきの言語でできないなんて……

for 文で一文字ずつ見ていって どこからどこまで取得するか決めて substring を取得するしかないのかなと諦めはじめてると 公式ドキュメントで drop というメソッドを見つけました
String のメソッドなので Linux でも使えます
Haskell の dropWhile みたいな感じで各文字に関数を実行して true が返ってくる限りは drop し続けるようです

これでやればできるかな と思ったのですが いきなり問題があって drop は前方向からしかできないみたいです
dropWhileEnd や dropAround にあたるものがありません
反対の意味で prefix を上げてる人もいましたが これは指定の文字がみつかるまで前から取得していくものです

「" a b "」 という文字列に半角スペースを指定して drop すれば 「a」 以降の文字列が取れます
その結果に prefix で半角スペースを指定しても取れるのは 「a b」 ではなく 「a」 になります
後ろから半角スペースを捨てていくのではなく 最初に条件に合う文字見つかった場所まで である以上 dropWhileEnd の代わりにはできません


他のメソッドを見ていると 文字列を反転する reversed メソッドがありました
これを組み合わせるとできそうです
反転してから drop を使えば元の文字列を後ろから drop できます
その後にもう一度反転して元の順に並べると後ろ側が drop されています
半角スペースと 「"」 の 2 つを対象に 「 \"a b c\" 」 を trim してみました

user@elem:~/swift-4.1.1-RELEASE-ubuntu16.04/usr/bin$ ./swift
Welcome to Swift version 4.1.1 (swift-4.1.1-RELEASE). Type :help for assistance.
1> let s = " \"a b c\" "
2. .drop { [" ", "\"" ].contains($0) }
3. .reversed()
4. .drop { [" ", "\"" ].contains($0) }
5. .reversed()
6. String(s)
$R0: String = "a b c"
s: ReversedCollection<Slice<ReversedCollection<String.SubSequence>>> = {
_base = {
_startIndex = {
base = {
_compoundOffset = 36
_cache = character {
character = {
stride = 1
}
}
}
}
_endIndex = {
base = {
_compoundOffset = 16
_cache = character {
character = {
stride = 1
}
}
}
}
_base = {
_base = {
_slice = {
_startIndex = {
_compoundOffset = 16
_cache = character {
character = {
stride = 1
}
}
}
_endIndex = {
_compoundOffset = 52
_cache = utf16
}
_base = " \"a b c\" "
}
}
}
}
}

すごく大変ですね
trim は他の機能の組み合わせでどうにかなりましたが 正規表現なんてどうすればいいの?というレベルです

Linux で使う言語じゃないようです

まだ Linux だと使えない NS 系の型を補う Polyfill のようなライブラリがあれば動くのかもしれませんが そこまでして Linux で使う意味も無さそうに思いますし 作る人がいるのかも疑問です
Linux で使う場合に Swift でないとできないことなんてないと思いますし 他の言語を使ったほうが良いと思います
Swift しか書けない Apple 系専門の人が Linux 使うことになったけど Linux でもちょっとしたプログラムは Swift で書きたい という場合くらいでしょうか