2020/2/28 Dart Future class

Future<T> class

時間のかかる計算を表現するオブジェクト

Futureクラスは未来のある時点で利用できる可能性のある潜在的な値、あるいはエラーを表現します。Futureインスタンスを受け取る変数などは利用可能になった時に値、あるいはエラーを扱うコールバック関数を登録することができます。例えば、

「値、あるいはエラーを利用可能になった時」とは、非同期処理が完了した時。

Future<int> future = getFuture();
future.then((value) => handleValue(value))
      .catchError((error) => handleError(error));

Futureインスタンスは二つの方法で完了(completed)することができます。

  • futureが成功する場合(値と共に完了する。)
  • futureが失敗する場合(エラーと共に完了する。)

上記二つのケースそれぞれにコールバックを登録することができます。(成功した時の処理、失敗した時の処理を登録できる、ということ。)

時に、「futureが、他のfutureと共に完了する」と表現するケースもあります。

 

 

 

 

 

 

参考

https://api.dart.dev/stable/2.7.1/dart-async/Future-class.html

2020/2/27 Dart Asynchronous programming: futures, async, await

このcodelabでは、非同期処理をfuturesとasync、awaitキーワードを用いて記述する方法を扱います。

このcodelabでは以下の要素を扱います。

  • いつ、どのようにasync、awaitキーワードを使うか
  • 実行の順番がasync、awaitキーワードを使うことでどのようになるか
  • async関数の中で、非同期関数が発するエラーをtry-catch文を使い扱う方法

なぜ非同期処理が重要なのか?(Why asynchronous code matters)

非同期処理を使うことで、別の処理の終了を待っているときのプログラムが完璧にできます。非同期処理を使う場面として

  • ネットワークからデータを取得する
  • データベースに書き込む
  • ファイルからデータを読み込む

Dartで非同期処理を実行するために、Futureクラスとasync、awaitキーワードを使うことができます。

Example:非同期関数の間違った使い方の例

以下(sample1-1)に非同期関数( fetchUserOrder() )の間違った使い方を示します。その後でasync,awaitを使ってこのサンプルを修正します。このサンプルを実行する前に、結果がどうなるか考えてみてください。

sample1-1

String createOrderMessage () {
  var order = fetchUserOrder();
  return 'Your order is: $order';
}

Future<String> fetchUserOrder() {
  // Imagine that this 

2020/2/14 Swift->Control Flow->While Loops

While Loops

whileループは条件式がfalseになるまでstatementsを実行する制御です。イテレーションが始まる前にイテレーションの回数がわからないような場合にwhileループを使用するのが適しています。Swiftは二つの種類のwhileループを提供します。

  • while文はループの最初に条件式を評価します。
  • repeat-while文はループの終わりに条件式を評価します。

while文

whileループは一つの条件式をループの最初に評価します。条件式がtrueと評価された場合、条件式がfalseと評価されるまで実行文が繰り返し実行されます。

while condition {
    statements
}

下のサンプルはシンプルなゲーム「Snakes and Ladders(へびとはしご)」です。

 

ルールは以下の通りです。

ボードには25のマスがあります。ゲームの目的(ゴール)は25マス目に到達、あるいは25マス目を超えることです。

  • スタート地点は「0マス目」であり、ボードの外にあります。
  • それぞれのターンで六面のサイコロを振り、図で示す道順に従いサイコロの結果の数だけ進みます。
  • 進んだ先にはしごの下端があれば、はしごを登ってはしごの上端まで進めます。
  • 進んだ先にへびの頭があれば、へびに食われてへびの尻尾まで戻されます。

ゲームのボードはInt型の配列で表現されます。ゲームボードのサイズは定数finalSquareの値に基づきます。ボードを表現する配列boardのイニシャライズにfinalSquareが使用されます。またこの後登場する勝利条件の判定にもfinalSquareが使用されます。配列boardは、プレーヤーのスタート地点も含めて全部で26(25ではなくて)のInt型の値0でイニシャライズされます。

let finalSquare = 25
var board = [Int](repeating: 0, count: finalSquare + 1)

いくつかのマス目は、へびとはしごを表現するために、特別に値をセットします。はしごの入り口のマス目には正の数値をセットしてボードを進めることを表現します。へびの頭のマス目には負の数値をセットしてボードを戻らなければならないことを表現します。

board[03] = +08; 

2020/2/8 Swift ジェネリック(Generics)パート2

連想型の型制約にプロトコルを使う(Using a Protocol in Its Associated Type’s Constraints)

プロトコル定義内の要求の中にプロトコルを出現させることもできます。例えば、suffix(_:)メソッドの実装の要求を追加して、Containerプロトコルを改良します(suffix:接尾辞)。suffix(_:)メソッドは与えられた数の要素をcontainerの末尾から取り出して返します。取り出された要素をSuffix型(連想型)のインスタンスに格納して返します。

protocol SuffixableContainer: Container {
    associatedtype Suffix: SuffixableContainer where Suffix.Item == Item
    func suffix(_ size: Int) -> Suffix
}

上の例のContainerプロトコルにおける連想型Itemのように、このプロトコルにおいてSuffixは連想型です。連想型Suffixには二つの制約があります。

  • Suffixは、SuffixableContainerプロトコル(まさに定義しようとしているプロトコル自身)に準拠した型を指定する必要がある。
  • SuffixのItem型とcontainerのItem型が同じ型出なければならない。

Itemへの制約はgeneric where clauseです。generic where clauseはこの後説明します。

sample3-2のジェネリック型のStack<Element>型をSuffixableContainerプロトコルに準拠させたのが、sample5-1です。

sample5-1

protocol SuffixableContainer: Container 

20202/4 Swift Nested Types

列挙型は特定のクラスや構造体の機能をサポートする生成されます。同様に、より複雑な型の中で使用するためだけにユーティリティなクラスを定義することがあります。これを実現するためSwiftはnested typesを用意しています。本体をサポートする列挙型・クラス・構造体を本体の型の定義内に定義することができます。

ある型を別の型の入れ子(ネスト)にするには、別の型の本体内にその型の定義を記述します。

Nested Typesのアクション

sample1-1はBlackjackCard構造体を定義しています。トランプゲームのブラックジャックがモデルです。BlackjackCard構造体は二つの入れ子の列挙型SuitとRankを含んでいます。

ブラックジャックではAceのカードは1あるいは11、どちらでも評価できます。この機能はValues構造体で表現します。Values構造体はRank列挙型の中に入れ子します。

struct BlackjackCard {

    // nested Suit enumeration
    enum Suit: Character {
        case spades = "♠", hearts = "♡", diamonds = "♢", clubs = "♣"
    }

    // nested Rank enumeration
    enum Rank: Int {
        

2020/2/1 Swift Conditional Statement->switch

switch文はある値を評価し、その結果をいくつかの可能性のあるパターンと比較します。そして、最初に合致したパターンと対応したコードブロックを実行します。switch文は、複数の可能性のある状態に対応するための、if文の代わりとなる構文です。

 

switch文は複数の可能性のあるケースにより構成されます。ケースは全て

caseキーワードで始まります。

 

 

2020/2/2 Swift パターン(Patterns)

 


識別子パターン(identifier pattern)

識別子パターンはあらゆる値とマッチし、マッチした値を変数名・定数名と結び付けます。例えば、下の定数の宣言ですが、someValueは識別子パターンで、Int型の42とマッチします。

let someValue = 42

マッチが成功すると、42という値は定数名someValueと結び付けられます(代入されます)。

定数宣言、変数宣言の左側が識別子パターンである時、その識別子パターンは暗黙的なバリューバインディングパターンのサブパターンです。


バリューバインディングパターン(value-binding pattern)

バリューバインディングパターンはマッチした値を変数名・定数名と結び付けます。バリューバインディングパターンでマッチした値を定数名と結びつけるにはletキーワードを最初に付けます。マッチした値を変数名と結びつけるにはvarキーワードを最初に付けます。

バリューバインディングパターンの一部である識別子パターンは、マッチした値を新しい変数名・定数名と結び付けます。例えば、タプルの要素を分解して各要素の値を対応する識別子パターンと結びつけることができます。

let point = (3, 2)
switch point {
    // pointの要素をxとyに結びつける。
case let (x, y):
    print("The point is at (\(x), \(y)).")
}
//