公開技術情報

[English] [Japanese]

13. accessor 編

今回はメンバの accessor について説明します。

accessor

メンバの accessor (get,set) を簡単に作成できます。

次に例を示します。

// @lnsFront: ok
class Test {
   pri let val1:int;
   pri let mut val2:int {pub,pub};
   pri let val3:int {pub};
}
let mut test = new Test( 1, 2, 3 );
print( test.$val2, test.$val3 );  // 2 3
test.set_val2( 10 );
print( test.$val2, test.$val3 );  // 10 3

上記例で val2 の定義は、 pri let val2:int {pub,pub}; としています。

この {pub,pub} は、 val2 の accessor を定義しています。 これは、 getter, setter のアクセス制御を指定します。 この指定によって、次のメソッドが内部的に作成されます。

// @lnsFront: skip
pub fn Test.get_val2(): int {
   return self.val2;
}
pub fn Test.set_val2( val:int ) {
   self.val2 = val;
}

getter にアクセスする場合、 $ を使って次のようにアクセスします。

// @lnsFront: skip
let mut test = new Test( 1, 2, 3 );
print( test.$val2, test.$val3 );  // 2 3

test.$val2 は、 test.get_val2() のシンタックスシュガーです。

上記の通り、 accessor は「getter のアクセス制御」、「setter のアクセス制御」の順で宣言します。

setter が不要な場合、「setter のアクセス制御」を省略します。

なお、getter が不要で setter が必要な場合は、次のように宣言します。

// @lnsFront: ok
class Test {
   pri let mut val1:int {non,pub};
}

この機能は、 setter を自動で生成しつつ、 getter をカスタマイズする時などに利用できます。

LuneScript の accessor は、普通のメソッドです。 C# のプロパティのような別のものではありません。

getter の戻り値型

getter の戻り値型は、通常そのメンバの型と一致します。

例えば次の Test のメンバ list の getter は、 List<int> 型の戻り値を返します。

// @lnsFront: ok
class Test {
   pri let mut list:List<int> {pub};
}
let test = new Test( [] );
foreach val in test.$list { 
   print( val );
}

ここで、 List<int> 型は mutable な型であるので、 外部操作でメンバ list の値を変更できることになります。

しかし、外部操作での参照は許可しても変更を許可したくない場面が多くあります。

そのような時、 getter の戻り値型を制御することが出来ます。 制限する方法は次の 2 つあります。

  • immutable な型として返す
  • super クラスや interface の型として返す

immutable な型として返す

getter を次のように宣言することで、 mutable なメンバを immutable として返す getter を作成できます。

// @lnsFront: ok
class Test {
   pri let mut list:List<int> {pub&};
}

この例では pub& としています。 getterの「アクセス制御」に & を付加することで、その戻り値型は immutable になります。

super クラスや interface の型として返す

getter を次のように宣言することで、 メンバの型そのものではなく、 super クラスや interface の型として返すことが出来ます。

// @lnsFront: ok
class Val {
}
class ValSub extend Val {
}

class Test {
   pri let val1:ValSub {pub};
   pri let val2:ValSub {pub:Val};
}
let test = new Test( new ValSub(), new ValSub() );
let val1 = test.$val1;
let val2 = test.$val2;

ここで、 Test.val1 の getter は pub ですが、 Test.val2 の getter は pub:Val としています。

これにより test.$val1ValSub 型を返しますが、 test.$val2 は Sub 型を返します。

accessor のカスタマイズ

LuneScript の accessor は、 C# のプロパティのようなカスタマイズ機能 (単純な setter/getter ではない処理を実装する機能)は用意していません。

なぜならば、 LuneScript の accessor は、単なるメソッド宣言の簡略化機能であり、 C# のプロパティのような「別物」ではないので、 もしも独自処理を行なう accessor が必要ならばその処理を自分で作成すれば良いためです。

なお、 独自の getter を定義した場合も $ は利用できます。

$val は、 get_val() のシンタックスシュガーで、accessor 専用ということではありません。

まとめ

LuneScript の accessor は次の仕様です。

  • メンバ宣言と同時に宣言出来る
  • getter, setter の順に宣言する
  • getter にアクセスする場合、 メンバ名の前に $ を付加する。
  • accessor は簡易メソッド定義であり、メソッドと異なる概念ではない。

次回は継承を説明します。