追記
Swift5.4ではこの制限はなくなりました。
本文
Swiftは変数名に日本語や絵文字や、その他のかなり多くの文字を使うことができます。
そこで英語の苦手な知人に日本語名の変数でいろいろ説明していたのですが、なんと「propertyWrapperでは日本語が使えない」という事実が明らかになったので、共有します。
環境はSwift5.3です。
実験
実際にはSwiftUIをいじっている際に起こったのですが、結局問題なのはpropertyWrapperなので一緒です。
まずはシンプルなラッパとそれを使う構造体を宣言します。ポイントは「値」という変数名です。
@propertyWrapper
struct MyWrapper<T>{
let wrappedValue: T
let projectedValue: T
init(wrappedValue value: T){
self.wrappedValue = value
self.projectedValue = value
}
}
struct MyValue{
@MyWrapper var 値 = 10
func print(){
//これは大丈夫
Swift.print(self._値)
//Error: '$' is not an identifier; use backticks to escape it
//Error: Value of type 'Value' has no member '$'
Swift.print(self.$値)
}
}
projectedValue
を使おうとすると「$
」が何かトラブルを起こしてエラーが出るようになります。使わなければエラーにはなりません。
試行錯誤
当初「日本語名で始まるのがまずいならアンダーバーでもつけとけば大丈夫でしょ」と高を括っていたのですが、ダメでした。
func print(){
Swift.print(self._値)
Swift.print(self.__値)
//Cannot find '値' in scope
Swift.print(self.$_値)
}
「アンダーバーはちょっと特殊な記号だから確かに良くないな」と改心してa
をつけてみたのですが、ダメでした。
func print(){
Swift.print(self.a値)
Swift.print(self._a値)
//Cannot find '値' in scope
Swift.print(self.$a値)
}
その後も試行錯誤を重ねましたが、結論としては一文字でも入っているとダメでした。これは日本語に限らず、英数字を除くほぼ全ての文字に加わる制約です。
#原因
$
の後の文字としてこれらの文字を使うことができない、という制約は特にありません。Developer Forumsの指摘によるとコンパイラのバグのようです。
こちらのPRでバグ自体は修正されているようですが、Swift5.3時点ではまだ修正が含まれておらず、この先のリリースでの修正となるそうです。もうしばらくの辛抱ですね。