2019/12/31 Swift プロパティ パート1

プロパティはクラス・構造体・列挙型に値を結びつけます。ストアドプロパティは定数や変数の値をインスタンスの一部として格納し、一方コンピューテドプロパティは値を計算します。コンピューテドプロパティはクラス・構造体・列挙型に存在し、ストアドプロパティはクラスと構造体に存在します。

ストアドプロパティとコンピューテドプロパティは通常特定の型のインスタンスに結びつけられます。しかしインスタンスではなく型そのものに結びつけられるプロパティもあります。タイププロパティとして知られています。

さらにプロパティの値の変化を検知するプロパティオブザーバと、変化に対応する独自の挙動を定義することができます。プロパティオブザーバーはあなたが定義したストアドプロパティに対して用意できます。さらにサブクラスがスーパークラスから継承したプロパティに対しても用意できます。

さらにゲッター・セッターとして用意したコードを、複数のプロパティに対して利用できる「プロパティラッパー」もあります。

ストアドプロパティ

ストアドプロパティは特定のクラス・構造体のインスタンスの一部としての定数・変数です。ストアドプロパティは変数のストアドプロパティ(varキーワードを使用)、定数のストアドプロパティ(letキーワードを使用)どちらも使用できます。

ストアドプロパティを宣言と同時に初期値を設定することができます。

下のサンプルはFixedLengthRangeという名の構造体を定義しています。整数の範囲を表す構造体で、インスタンス生成後範囲の変更はできないものです。

struct FixedLengthRange {
    var firstValue: Int
    let length: Int
}
var rangeOfThreeItems = FixedLengthRange(firstValue: 0, length: 3)
// the range represents integer values 0, 1, and 2
rangeOfThreeItems.firstValue = 6
// the 

2019/12/19 Dart 関数(Functions)パート3

無名関数

main()関数やprintElement()関数のように、ほとんどの関数は関数名を持っていますが、名前のない関数を定義することもできます。無名関数はラムダ関数やクロージャーとも呼ばれることもあります。

無名関数の定義方法は通常の名前のある関数と似ています。0個、あるいは一つ以上の引数をカンマ(,)で区切り、型注釈を記述することもできますし、型注釈を記述しなくても問題ありません。

sample1-1

  var list = ['apples', 'bananas', 'oranges'];
  list.forEach((item) {
    print('${list.indexOf(item)}: $item');
  });
  
  list.forEach(
    (item) => print('${list.indexOf(item)}: $item')
  );
//0: apples
//1: bananas
//2: oranges
//0: apples
//1: bananas
//2: oranges

sample1-1では型注釈のない引数itemを取る無名関数を定義しています。無名関数はリストの各要素を受け取り、インデックス番号と文字列を表示します。

sample1-1の後半にあるように、関数の本体が一文の時アロー構文を用いて記述することができます。


レキシカルスコープ(静的スコープ)

Dartはレキシカルスコープ(静的スコープ)の言語です。

工事中🏗

参考

https://dart.dev/guides/language/language-tour#built-in-types

2019/12/19 Dart 関数(Functions)パート2

関数には二つのタイプの引数、「必須の引数」と「オプショナル引数」があります。引数が複数ある時「必須の引数」が最初に配置され、その後ろに「オプショナル引数」を配置します。オプショナル引数は「namedオプショナル引数」と「positionalオプショナル引数」に分けられます。

オプショナル引数

オプショナル引数は「namedオプショナル引数」か「positionalオプショナル引数」のどちらかです。

Named parameters

sample1-1

  //関数定義時のNamed parameterの使い方
  void enableFlags({bool bold, bool hidden}){
    print("${bold},${hidden}");
  }
  
  //関数実行時のNamed parameterの使い方
  enableFlags(bold : true,hidden : false);
  //true,false

上記の通りです。

関数定義時に引数がNamed parametersであることを示すために、上記のように引数を{ }で囲みます。

関数実行時の引数を、

(bold : 引数boldに渡す値,hidden : 引数hiddenに渡す値)

のように記述します。

sample1-1では関数定義時、第一引数がbold、第二引数がhiddenですが、

実行時、第一引数にhiddenを、第二引数にboldを指定することもできます。(sample1-2)

sample1-2

  //関数定義時のNamed parameterの使い方
  void 

2019/12/19 Dart 関数(Functions)パート1

Dartは真のオブジェクト指向言語ですので、関数もオブジェクトであり、関数型(Function type)が用意されています。これは、関数を変数に代入することができ、関数を別の関数の引数として渡すことができる、ということです。Dartクラスのインスタンスを関数のように呼び出すこともできます。

sample1-1(関数定義の例)

  var _nobleGases = {
  2: 'helium',
  10: 'neon',
  18: 'argon',
};
  
  bool someFunc(int para1){
    return _nobleGases[para1] != null;
  }
  
  print(someFunc(2));  //true
  print(someFunc(1));  //false
  print(someFunc(10));  //true
  print(someFunc(3));  //false

sample1-1ではsomeFuncという関数名の関数を定義しています。型注釈として戻り値の型をbool型、引数の型をInt型と指定しています。

引数で指定したkeyに値が存在する場合はtrueを、値がない場合はfalseを返す関数です。

sample1-2

  var _nobleGases = {
  2: 'helium',
  10: 

2019/12/19 Dart セット(sets)

セット(sets)

Dartのセット(set)は順番のないコレクションで、全ての要素がユニークでないといけません。一つのセット内に同じ値の要素があってはいけません。

sample1-1はセットリテラルでの変数定義です。

sample1-1

var halogens = {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'};
  
print(halogens);  //{fluorine, chlorine, bromine, iodine, astatine}

上記サンプルで変数halogensはSet<String>型と型推定されます。このセットにString型以外の値を要素に加えようとすると実行時エラーとなります。

空のセットを作る場合(sample1-2)

(1)型引数の後に{}を記述する

(2)型注釈でSet<String>型を指定した変数に{}を代入する。

sample1-2

var names1 = <String>{};  //(1)
Set<String> names2 = {};  // (2)

print(names1);  //{}
print(names2);  //{}

既存のセットに要素を追加する場合add()メソッドあるいはaddAll()メソッドを使います。

セットの要素数を取得する時はセットのlengthプロパティを使います。…

2019/12/19 Dart 真偽値型( Booleans ) , リスト ( Lists ) , collection if , collection for の訳

真偽値(bool型)

真偽値を表すためにDartにはbool型が用意されています。bool型のリテラルはtrueとfalseです。どちらもコンパイル時定数です。

//空文字列であればtrueを返すisEmptyプロパティ
var fullName = '';
print(fullName.isEmpty);  //true

var hitPoints = 0;
print(hitPoints<=0);  //true

var unicorn;
print(unicorn == null);  //true

リスト(List)

ほぼ全てのプログラミング言語において最も一般的なコレクションは配列(array)、あるいは順序づけられたオブジェクトのグループですが、Dartではリストオブジェクトです。

リストリテラルはjavascriptの配列リテラルの記述法と似ています。sample2-1はシンプルなリストの定義です。

var list = [1, 2, 3];

上記で変数listはList<int>型と型推定されます。もしこのlistに整数値以外のオブジェクトを追加しようとすると実行時エラーとなります。

リストは0から始まるインデックスが使われます。インデックス0はリストの最初の要素を指し、list.length-1はリストの最後の要素を指します。

var list = [1, 2, 3];
print(list.length == 

2019/12/19 Dart 数値型、文字列型

数値型

Dartの数値型にはint型とdouble型があります。

int型は整数型です。小数点のない数値です。sample1-1はInt型の変数宣言の例です。

var x = 1;
var hex = 0xDEADBEEF;
  print(x);    //1
  print(hex);    //3735928559

小数点のある数値はdouble型です。sample1-2はdouble型の変数宣言の例です。

var y = 1.1;
var exponents = 1.42e5;
  print(y);    //1.1
  print(exponents);    //142000

Dart2.1からは整数リテラルは必要な時に自動的にdouble型に変換されます。

数値リテラルはコンパイル時定数です。オペランドが数値と評価されるコンパイル時定数である限り計算式もコンパイル時定数です。

const msPerSecond = 1000;
const secondsUntilRetry = 5;
const msUntilRetry 

2019/12/18 Dart 変数、定数( final , const)、組み込み型

変数

Dartでの変数宣言と初期化方法。

var name = 'Bob';

型注釈をせずに変数宣言する場合上記のようにvarキーワードを使います。変数は参照を格納します。上記サンプルでは変数nameは”Bob”という文字列値を持つString型のオブジェクトへの参照を保持します。

変数nameに型注釈(アノテーション)はありませんが、変数nameはString型と型推定されます。変数の型を単一の型に制限したくない場合は、Object型、またはdynamic型を指定します。

dynamic name = 'Bob';

変数の型を明示的に宣言(型注釈)する場合は↓

String name = 'Bob';

型名 変数名=リテラル;

です。


変数を宣言して初期化しないと自動的にnullがセットされます。

  String c;
  print(c==null);  //true<br>  int d;<br>  print(d==null);  //true<br>

定数

値を変更することがない場合(つまり定数)は、varキーワードではなくfinalキーワードまたはconstキーワードを使用します。finalキーワードで宣言した定数は一度だけ値をセットできます。

constキーワードを用いて宣言した定数はコンパイル時定数です。((Const variables)const定数は暗黙的にfinalです。)

Note:インスタンス変数はfinalで宣言します。constでは宣言しません。finalで宣言されたインスタンス変数は、コンストラクタのボディが始まる前に初期化する必要があります。具体的には

–インスタンス変数の宣言時、

–コンストラクタの引数での初期化

–コンストラクタのイニシャライザリストでの初期化

のいずれかで初期化する必要があります。

2019/12/17 Swift オプショナル型 パート3(オプショナルチェイニング)

オプショナルチェイニング(Optional chaining)はnilかもしれないオプショナル型インスタンスのプロパティ・メソッド・サブスクリプトへアクセスする方法です。オプショナル型インスタンスに値がある場合、プロパティ・メソッド・サブスクリプの呼び出しは成功します。オプショナル型インスタンスがnilの場合、プロパティ・メソッド・サブスクリプトの呼び出しはnilを返します。

強制アンラップの代わりとしてのオプショナルチェイニング

オプショナルチェイニングの記述方法

 

オプショナルチェイニングの書き方は、値がnilでない場合に呼び出したいプロパティ・メソッド・サブスクリプトの属するオプショナル型インスタンスの後ろに?を記述します。強制アンラップの記述法とよく似ています。この二つの一番の違いは、値がnilの場合の挙動です。強制アンラップの場合値がnilだと実行時エラーになりますが、オプショナルチェイニングの場合正常に失敗します。

 

問い合わせたプロパティ・メソッド・サブスクリプトが非オプショナル型の値を返す場合であっても、「オプショナルチェイニングはnil値を呼び出せる」という事実を反映するために、オプショナルチェイニングの結果は常にオプショナル型の値となります。オプショナルチェイニングが成功したか(返されたオプショナル型が値を保持している)、オプショナルチェイニングの連鎖の中にnilがあることで失敗した(返されたオプショナル型がnilである)かを調べるために、返されたオプショナル型の値を使うことができます。

 

呼び出したいプロパティ・メソッド・サブスクリプトが非オプショナルの値であっても、オプショナルチェイニングの結果は常にオプショナル型の値となります。値がnilの場合でもオプショナルチェイニングを呼び出せるということになので、失敗可能でなければならない、ということ。オプショナルチェイニングが成功(結果のオプショナル型が値を保持している)したか、あるいは失敗したかを調べることで、オプショナルチェイニングの結果を使うことができます。

具体的には、オプショナルチェイニングの結果は返される値の型と同じ型であるが、オプショナル型である。Int型のプロパティにオプショナルチェイニングでアクセスするとInt?型を返します。

次のコードは、オプショナルチェイニングと強制アンラップの違い、そしてオプショナルチェイニングによる参照が成功したかを調べる方法を示します。

まずPersonとResidenceという名前の二つのクラスを定義します。

class Person {
    var residence: Residence?
}

class Residence {
    var numberOfRooms = 1
}

ResidenceインスタンスはnumberOfRoomsという名前で初期値が1のInt型のプロパティを持っています。PersonインスタンスはResidence?型の、residenceという名前のプロパティを持っています。

新たにPersonインスタンスを作った時、そのインスタンスのresidenceプロパティは(自動的に)nilで初期化されます(residenceがオプショナル型だから)。下のコードでjohnは値がnilであるresidenceプロパティを持っています。

let john = Person()

定数johnのresidenceプロパティのnumberOfRoomsプロパティに、強制アンラップ(residenceの後ろにエクスクラメーションマーク(