欠如

来世は貝になりたい

ツアーの旅Error Handling

どうもツアーの旅です。 今日のツアーテーマはError Handlingについてです。

まずはじめに エラーハンドリングとは何かですが IT用語辞典によるところ エラーハンドリング(error handling)とは、本来の処理が正常に終了しなかった際に発生するエラーをトラップし、プログラムを正常な状態に復帰させる処理。 みたいです。

You represent errors using any type that adopts the Error protocol.

エラープロトコルを採用しているすべてのタイプを使用してエラーを表現します。

enum PrinterError: Error { case outOfPaper case noToner case onFire }

Use throw to throw an error and throws to mark a function that can throw an error. If you throw an error in a function, the function returns immediately and the code that called the function handles the error.

throwを使用してエラーをスローし、スローしてエラーをスローする可能性のある関数をマークします。   関数にエラーを投げた場合、関数はすぐに戻り、関数を呼び出したコードがエラーを処理します。

func send(job: Int, toPrinter printerName: String) throws -> String { if printerName == “Never Has Toner” { throw PrinterError.noToner } return “Job sent” }

There are several ways to handle errors. One way is to use do-catch. Inside the do block, you mark code that can throw an error by writing try in front of it. Inside the catch block, the error is automatically given the name error unless you give it a different name.

エラーを処理するにはいくつかの方法があります。 1つの方法は、do-catchを使用することです。   doブロックの中で、その前にtryを書くことによってエラーを投げることができるコードをマークします。 catchブロックの内部では、別の名前を指定しない限り、エラーには自動的に名前エラーが与えられます。

do { let printerResponse = try send(job: 1040, toPrinter: “Bi Sheng”) print(printerResponse) } catch { print(error) }

実行すると1つ前のfunc sendのエラーが回避されて"Job sent"が表示されます。

You can provide multiple catch blocks that handle specific errors. You write a pattern after catch just as you do after case in a switch.

特定のエラーを処理する複数のキャッチブロックを提供できます。   あなたは、スイッチのケースの後と同じように、キャッチ後にパターンを書きます。

do { let printerResponse = try send(job: 1440, toPrinter: “Gutenberg”) print(printerResponse) } catch PrinterError.onFire { print(“I’ll just put this over here, with the rest of the fire.”) } catch let printerError as PrinterError { print(“Printer error: (printerError).”) } catch { print(error) }

Another way to handle errors is to use try? to convert the result to an optional. If the function throws an error, the specific error is discarded and the result is nil. Otherwise, the result is an optional containing the value that the function returned.

エラーを処理する別の方法はtryを使うことです? 結果をオプションに変換します。 関数がエラーをスローすると、特定のエラーは破棄され、結果はnilになります。 それ以外の場合、結果は、関数が戻した値を含むオプションです。

let printerSuccess = try? send(job: 1884, toPrinter: “Mergenthaler”) let printerFailure = try? send(job: 1885, toPrinter: “Never Has Toner”)

Use defer to write a block of code that is executed after all other code in the function, just before the function returns. The code is executed regardless of whether the function throws an error. You can use defer to write setup and cleanup code next to each other, even though they need to be executed at different times.

deferを使用して、関数内の他のすべてのコードの後、関数が返される直前に実行されるコードブロックを記述します。 コードは、関数がエラーをスローするかどうかに関係なく実行されます。 異なるタイミングで実行する必要がある場合でも、deferを使用して、セットアップコードとクリーンアップコードを互いに隣に書き込むことができます。

var fridgeIsOpen = false let fridgeContent = [“milk”, “eggs”, “leftovers”]

func fridgeContains(_ food: String) -> Bool { fridgeIsOpen = true defer { fridgeIsOpen = false }

let result = fridgeContent.contains(food)
return result

} fridgeContains(“banana”) print(fridgeIsOpen)

ツアーですねProtocols and Extensions

ツアーですね 今回はProtocols and Extensions プロトコルと拡張がテーマとなります。

まずはじめにプロトコルとは何かですが Wikiでは以下の通りに載ってます

プロトコルまたはプロトコール(英語: protocol 英語発音: [ˈproutəˌkɔːl] プロウタコール、[ˈproutəˌkɔl] プロウタコル、フランス語: protocole フランス語発音: [prɔtɔkɔl] プロトコル)とは、 複数の者が対象となる事項を確実に実行するための手順等について定めたもの。

Use protocol to declare a protocol. プロトコルを使用してプロトコルを宣言します。

protocol ExampleProtocol { var simpleDescription: String { get } mutating func adjust() }

Classes, enumerations, and structs can all adopt protocols. クラス、列挙体、および構造体は、すべてプロトコルを採用できます。

class SimpleClass: ExampleProtocol { var simpleDescription: String = “A very simple class.” var anotherProperty: Int = 69105 func adjust() { simpleDescription += “ Now 100% adjusted.” } } var a = SimpleClass() a.adjust() let aDescription = a.simpleDescription

struct SimpleStructure: ExampleProtocol { var simpleDescription: String = “A simple structure” mutating func adjust() { simpleDescription += “ (adjusted)” } } var b = SimpleStructure() b.adjust() let bDescription = b.simpleDescription

Notice the use of the mutating keyword in the declaration of SimpleStructure to mark a method that modifies the structure. The declaration of SimpleClass doesn’t need any of its methods marked as mutating because methods on a class can always modify the class.

SimpleStructureの宣言でmutatingキーワードを使用して構造を変更するメソッドをマークすることに注目してください。 SimpleClassの宣言では、クラスのメソッドは常にクラスを変更できるため、そのメソッドの中には突然変異としてマークされているものは必要ありません。

Use extension to add functionality to an existing type, such as new methods and computed properties. You can use an extension to add protocol conformance to a type that is declared elsewhere, or even to a type that you imported from a library or framework.

拡張機能を使用して、新しいメソッドや計算されたプロパティなど、既存のタイプに機能を追加します。 拡張機能を使用して、他の場所で宣言されている型、またはライブラリやフレームワークからインポートした型にプロトコル準拠を追加することができます。

extension Int: ExampleProtocol { var simpleDescription: String { return “The number (self)” } mutating func adjust() { self += 42 } } print(7.simpleDescription)

上記を実行するとThe number (self)となりselfに7が入る形になります

You can use a protocol name just like any other named type—for example, to create a collection of objects that have different types but that all conform to a single protocol. When you work with values whose type is a protocol type, methods outside the protocol definition are not available.

プロトコル名は、他の名前付きタイプと同じように使用できます。たとえば、異なるタイプのオブジェクトのコレクションを作成しますが、すべてが単一のプロトコルに準拠しています。 タイプがプロトコルタイプである値を操作する場合、プロトコル定義外のメソッドは使用できません。

protocol ExampleProtocol { var simpleDescription: String { get } mutating func adjust() } class SimpleClass: ExampleProtocol { var simpleDescription: String = “A very simple class.” var anotherProperty: Int = 69105 func adjust() { simpleDescription += “ Now 100% adjusted.” } } var a = SimpleClass() a.adjust() let aDescription = a.simpleDescription

let protocolValue: ExampleProtocol = a print(protocolValue.simpleDescription) // print(protocolValue.anotherProperty) // Uncomment to see the error (コメントを外すとエラー)

表示結果としてはA very simple class. Now 100% adjusted. となります。

Even though the variable protocolValue has a runtime type of SimpleClass, the compiler treats it as the given type of ExampleProtocol. This means that you can’t accidentally access methods or properties that the class implements in addition to its protocol conformance.

変数protocolValueに実行時の型SimpleClassがある場合でも、コンパイラはそれを指定された型のExampleProtocolとして扱います。 つまり、プロトコルの適合性に加えて、クラスが実装するメソッドやプロパティに誤ってアクセスすることはできません。

久しぶりのツアーですね Enumerations and Structures

久しぶりのツアーですね テーマはEnumerations and Structures 列挙と構造体となります。

構造体(こうぞうたい、英: structure)はプログラミング言語におけるデータ型の一つで、1つもしくは複数の値をまとめて格納できる型。(wiki) 列挙型(れっきょがた、enumerated type)とは、コンピュータプログラミングにおいて、プログラマが選んだ各々の識別子をそのまま有限集合として持つ抽象データ型である。列挙型は一般に、カードのスートのように番号順を持たないカテゴリ変数として使われるが、実際のコンパイル時あるいは実行時には、列挙型は整数で実装されることが多い。各々の識別子は通例異なる整数値を持つが、複数の識別子に対して意図的に同じ整数値を割り当てる(つまり別名を定義する)ことも可能である。(うぃき)

Use enum to create an enumeration. Like classes and all other named types, enumerations can have methods associated with them.

enumを使用して列挙を作成します。 クラスや他のすべての名前付き型と同様に、列挙型はそれらに関連付けられたメソッドを持つことができます。

enum Rank: Int { case ace = 1 case two, three, four, five, six, seven, eight, nine, ten case jack, queen, king func simpleDescription() -> String { switch self { case .ace: return “ace” case .jack: return “jack” case .queen: return “queen” case .king: return “king” default: return String(self.rawValue) } } } let ace = Rank.ace let aceRawValue = ace.rawValue

上記の結果において 例えば let aces = Rank.jack print(aces) と追加して追記すると func simpleDescription()のswitch文の対応するcaseが返ってきます この場合だとjackなのでprintにはjackという文字列が入ります

By default, Swift assigns the raw values starting at zero and incrementing by one each time, but you can change this behavior by explicitly specifying values. In the example above, Ace is explicitly given a raw value of 1, and the rest of the raw values are assigned in order. You can also use strings or floating-point numbers as the raw type of an enumeration. Use the rawValue property to access the raw value of an enumeration case.

デフォルトでは、Swiftは0から始まり1ずつ増分する生の値を割り当てますが、値を明示的に指定することでこの動作を変更できます。 上記の例では、Aceに明示的に1の生の値が与えられ、残りの生の値は順番に割り当てられます。 列挙型の生の型として文字列または浮動小数点数を使用することもできます。 列挙ケースの生の値にアクセスするには、rawValueプロパティを使用します。

Use the init?(rawValue:) initializer to make an instance of an enumeration from a raw value. It returns either the enumeration case matching the raw value or nil if there is no matching Rank.

init?(rawValue :)イニシャライザを使用して、生の値から列挙のインスタンスを作成します。 生の値と一致する列挙ケースを返します。一致するRankがない場合はnilを返します。

enum Suit { case spades, hearts, diamonds, clubs func simpleDescription() -> String { switch self { case .spades: return “spades” case .hearts: return “hearts” case .diamonds: return “diamonds” case .clubs: return “clubs” } } } let hearts = Suit.hearts let heartsDescription = hearts.simpleDescription()

こちらの例だと先程の例と異なりCaseのheartsを指定しているので case内の"hearts"が文字列として返されます

Notice the two ways that the hearts case of the enumeration is referred to above: When assigning a value to the hearts constant, the enumeration case Suit. hearts is referred to by its full name because the constant doesn’t have an explicit type specified. Inside the switch, the enumeration case is referred to by the abbreviated form . hearts because the value of self is already known to be a suit. You can use the abbreviated form anytime the value’s type is already known.

上記の列挙の心臓ケースが上で言及される2つの方法に注目してください。心臓に値を割り当てるときは、列挙ケースSuit。 心臓は、定数に明示的な型が指定されていないため、フルネームで参照されます。 スイッチの内部では、列挙ケースは省略形で参照されます。 心の価値はすでにスーツであることが知られているからです。 値の型がすでにわかっているときはいつでも省略形を使用できます。

If an enumeration has raw values, those values are determined as part of the declaration, which means every instance of a particular enumeration case always has the same raw value. Another choice for enumeration cases is to have values associated with the case—these values are determined when you make the instance, and they can be different for each instance of an enumeration case. You can think of the associated values as behaving like stored properties of the enumeration case instance. For example, consider the case of requesting the sunrise and sunset times from a server. The server either responds with the requested information, or it responds with a description of what went wrong.

列挙型に生の値がある場合、それらの値は宣言の一部として決定されます。つまり、特定の列挙型のすべてのインスタンスが常に同じ生の値を持つことを意味します。 列挙ケースの別の選択肢は、ケースに関連付けられた値を持つことです。これらの値は、インスタンスの作成時に決定され、列挙ケースの各インスタンスごとに異なる場合があります。 関連付けられた値は、列挙型のインスタンスの格納されたプロパティのように動作すると考えることができます。 たとえば、サーバーから日の出と日没の時刻を要求する場合を考えてみましょう。 サーバーは要求された情報で応答するか、何が問題になったのかの説明で応答します。

enum ServerResponse { case result(String, String) case failure(String) }

let success = ServerResponse.result(“6:00 am”, “8:09 pm”) let failure = ServerResponse.failure(“Out of cheese.”)

switch success { case let .result(sunrise, sunset): print(“Sunrise is at (sunrise) and sunset is at (sunset).”) case let .failure(message): print(“Failure… (message)”) }

上記はenumで作ったcaseに対応してsucces,failureの2つでデータを挿入しswitchで指定したデータを回す感じになっております 現在switch文はsuccessを対象としているので結果はprint(“Sunrise is at (sunrise) and sunset is at (sunset).”)こちらに上記のいれたsuccessのデータが入り表示されます。

Notice how the sunrise and sunset times are extracted from the ServerResponse value as part of matching the value against the switch cases.

スイッチのケースと値を照合する際に、ServerResponseの値から日の出と日没の時刻がどのように抽出されているかに注目してください。

Use struct to create a structure. Structures support many of the same behaviors as classes, including methods and initializers. One of the most important differences between structures and classes is that structures are always copied when they are passed around in your code, but classes are passed by reference.

structを使用して構造体を作成します。 構造体は、メソッドや初期化子を含むクラスと同じ動作の多くをサポートしています。 構造とクラスの最も重要な違いの1つは、構造がコード内を渡されたときに常にコピーされますが、クラスは参照によって渡されるということです。

struct Card { var rank: Rank var suit: Suit func simpleDescription() -> String { return “The (rank.simpleDescription()) of (suit.simpleDescription())” } } let threeOfSpades = Card(rank: .three, suit: .spades) let threeOfSpadesDescription = threeOfSpades.simpleDescription()

こちらは以前作ったenumのデータを参照しデータを表示をしております 今回の例で言うとrankにあるthreeという数値、suitにあるspadesという文字列を参照しreturnで返しています

まぁ久しぶりの更新だったので勉強しつつやっていきたいと思います

お知らせ

私ごとでありますが 厄介な一部ユーザーから執拗なスター連呼をされ大変困っているので一時的にスターの機能は解除しております

何卒ご了承のほどお願いします。

暇つぶしのFizzBuzz

前回はif文ベースのSwiftでのFizzBuzzで考えましたが今回は while Repeat + switch文でのSwiftで考えました 結果はこんな感じです。

var m = 0
repeat {
    m += 1
    //print(m)
    switch m {
        case  (let test) where test % 3 == 0 && test % 5 == 0:
        print("\(m).FizzBuzz")
        case  (let test) where test % 3 == 0 :
        print("\(m).Fizz")
        case  (let test) where test % 5 == 0 :
        print("\(m).Buzz")
        default:
        print(m)
    }
    
} while m < 100

ソースはこの辺にあります

github.com

なんとなくFizzBuzzの計算をやってみる

よく面談の際にペーパーでFizzBuzzをやらされるのでSwiftでそれっぽい書き方を考える。

FizzBuzz

概要としては 1.3で割り切れる場合は「Fizz」(Bizz Buzzの場合は「Bizz」)、 2.5で割り切れる場合は「Buzz」 3.両者で割り切れる場合(すなわち15で割り切れる場合)は「Fizz Buzz」

上記の1〜3を満たすことが必要。

まずは普通にそれっぽく雑に書いてみる

var total = 0 for i in 0..<100 { total = total+1 if(total % 3 == 0 && total % 5 == 0){ print(“FizzBuzz”) }else if(total % 3 == 0){ print(“Fizz”) }else if(total % 5 == 0){ print(“Buzz”) } print(total) }

とりあいずこんな感じ。 要件としては1〜3を満たしているし問題なく動くので条件を満たして動くという意味では正解。 時折時間を見つけて条件を満たす計算方法を考えてみる。

随時更新します

ソースはこの辺に載せていくのでたまに見てくれればいいです

Swiftの文法について復習してみるObjects and Classes

ツアーもやっと中盤まで行きましたね 今回のテーマはObjects and Classes(オブジェクトとクラス)となります。

Objects and Classes

Use class followed by the class’s name to create a class. 
A property declaration in a class is written the same way as a constant or variable declaration, except that it is in the context of a class. 
Likewise, method and function declarations are written the same way.

クラスを作成するには、クラス名の後にクラスを使用します。
クラス内のプロパティ宣言は、クラスのコンテキスト内にあることを除いて、定数宣言または変数宣言と同じ方法で記述されます。
同様に、メソッドと関数の宣言も同じように記述されます。
class Shape {
    var numberOfSides = 10
    func simpleDescription() -> String {
        return "A shape with \(numberOfSides) sides."
    }
}
print(Shape().simpleDescription())

実行すると以下の通りになります

Linking ./.build/x86_64-unknown-linux/debug/TempCode
A shape with 10 sides.
Create an instance of a class by putting parentheses after the class name. 
Use dot syntax to access the properties and methods of the instance.

クラス名の後に括弧を入れてクラスのインスタンスを作成します。
ドット構文を使用して、インスタンスのプロパティとメソッドにアクセスします。
var shape = Shape()
shape.numberOfSides = 7
var shapeDescription = shape.simpleDescription()

こちらはすでにひとつ前の例に組み込む形になりますが 上のfuncとclassを代入し使いやすくした形になります。 なので結果表示は割愛します。

This version of the Shape class is missing something important: 
an initializer to set up the class when an instance is created. 
Use init to create one.

このバージョンのShapeクラスには、インスタンスの作成時にクラスを設定するためのイニシャライザという重要なものがありません。
initを使用して作成します。
class NamedShape {
    var numberOfSides: Int = 0
    var name: String
    
    init(name: String) {
        self.name = name
    }
    init(){
        self.name = "damy"
    }
    
    func simpleDescription() -> String {
        return "A shape with \(numberOfSides) sides."
    }
}
let test = NamedShape(name:"abs")
print(test.name)
print(NamedShape().simpleDescription())

今回は一部引数を使わない用に引数なしで公式とは変更があります・ ちなみに実行すると以下のような結果が得られます

Linking ./.build/x86_64-unknown-linux/debug/TempCode
abs
A shape with 0 sides.
Notice how self is used to distinguish the name property from the name argument to the initializer. 
The arguments to the initializer are passed like a function call when you create an instance of the class. 
Every property needs a value assigned—either in its declaration (as with numberOfSides) or in the initializer (as with name).

nameプロパティとname引数を初期化子と区別するためにselfがどのように使用されているかに注目してください。
イニシャライザへの引数は、クラスのインスタンスを作成するときに関数呼び出しのように渡されます。
すべてのプロパティは、宣言(numberOfSidesの場合)またはイニシャライザ(nameの場合)のいずれかに値を割り当てる必要があります。
Use deinit to create a deinitializer if you need to perform some cleanup before the object is deallocated.

Subclasses include their superclass name after their class name, separated by a colon. 
There is no requirement for classes to subclass any standard root class, so you can include or omit a superclass as needed.

オブジェクトの割り当てが解除される前にいくつかのクリーンアップを実行する必要がある場合は、deinitを使用してdeinitializerを作成します。

サブクラスは、クラス名の後ろにコロンで区切られたスーパークラス名を含みます。
クラスが標準のルートクラスをサブクラス化する必要はないため、必要に応じてスーパークラスを含めるか省略することができます。
Methods on a subclass that override the superclass’s implementation are marked with override—
overriding a method by accident, without override, is detected by the compiler as an error. 
The compiler also detects methods with override that don’t actually override any method in the superclass.

スーパークラスの実装をオーバーライドするサブクラスのメソッドには、オーバーライドなしでメソッドが
オーバーライドされてマークされ、エラーとしてコンパイラによって検出されます。
また、コンパイラは、スーパークラスのメソッドを実際にオーバーライドしないオーバーライドを持つメソッドも検出します。
class Square: NamedShape {
    var sideLength: Double
    
    init(sideLength: Double, name: String) {
        self.sideLength = sideLength
        super.init(name: name)
        numberOfSides = 4
    }
    
    func area() -> Double {
        return sideLength * sideLength
    }
    
    override func simpleDescription() -> String {
        return "A square with sides of length \(sideLength)."
    }
}
let test = Square(sideLength: 5.2, name: "my test square")
test.area()
test.simpleDescription()

前例のNamedShape CLASSを継承し 実行結果は以下となります

Linking ./.build/x86_64-unknown-linux/debug/TempCode
27.04
A square with sides of length 5.2.
In addition to simple properties that are stored, properties can have a getter and a setter.

格納される単純なプロパティに加えて、プロパティにはゲッタとセッタがあります。
class EquilateralTriangle: NamedShape {
    var sideLength: Double = 0.0
    
    init(sideLength: Double, name: String) {
        self.sideLength = sideLength
        super.init(name: name)
        numberOfSides = 3
    }
    
    var perimeter: Double {
        get {
            return 3.0 * sideLength
        }
        set {
            sideLength = newValue / 3.0
        }
    }
    
    override func simpleDescription() -> String {
        return "An equilateral triangle with sides of length \(sideLength)."
    }
}
var triangle = EquilateralTriangle(sideLength: 3.1, name: "a triangle")
print(triangle.perimeter)
triangle.perimeter = 9.9
print(triangle.sideLength)

前例のNamedShape CLASSを継承し 実行結果は以下となります

Linking ./.build/x86_64-unknown-linux/debug/TempCode
9.3
3.3
In the setter for perimeter, the new value has the implicit name newValue. You can provide an explicit name in parentheses after set.

格納される単純なプロパティに加えて、プロパティにはゲッタとセッタがあります。
Notice that the initializer for the EquilateralTriangle class has three different steps:

1. Setting the value of properties that the subclass declares.
2. Calling the superclass’s initializer.
3. Changing the value of properties defined by the superclass. 
Any additional setup work that uses methods, getters, or setters can also be done at this point.

EquilateralTriangleクラスのイニシャライザには、次の3つのステップがあります。

1.サブクラスが宣言するプロパティの値を設定する。
2.スーパークラスの初期化子を呼び出す。
3.スーパークラスによって定義されたプロパティの値を変更する。
メソッド、ゲッター、またはセッターを使用する追加のセットアップ作業もこの時点で実行できます。
If you don’t need to compute the property but still need to provide code that is run before and after setting a new value, use willSet and didSet. 
The code you provide is run any time the value changes outside of an initializer. 
For example, the class below ensures that the side length of its triangle is always the same as the side length of its square.

プロパティを計算する必要はなく、新しい値を設定する前後に実行されるコードを提供する必要がある場合は、willSetとdidSetを使用します。
指定したコードは、イニシャライザの外部で値が変更されるたびに実行されます。
たとえば、以下のクラスは、三角形の辺の長さが常に四角形の辺の長さと同じであることを保証します。
class TriangleAndSquare {
    var triangle: EquilateralTriangle {
        willSet {
            square.sideLength = newValue.sideLength
        }
    }
    var square: Square {
        willSet {
            triangle.sideLength = newValue.sideLength
        }
    }
    init(size: Double, name: String) {
        square = Square(sideLength: size, name: name)
        triangle = EquilateralTriangle(sideLength: size, name: name)
    }
}
var triangleAndSquare = TriangleAndSquare(size: 10, name: "another test shape")
print(triangleAndSquare.square.sideLength)
print(triangleAndSquare.triangle.sideLength)
triangleAndSquare.square = Square(sideLength: 50, name: "larger square")
print(triangleAndSquare.triangle.sideLength)
Linking ./.build/x86_64-unknown-linux/debug/TempCode
10.0
10.0
50.0
When working with optional values, you can write ? before operations like methods, properties, and subscripting. 
If the value before the ? is nil, everything after the ? is ignored and the value of the whole expression is nil.
 Otherwise, the optional value is unwrapped, and everything after the ? acts on the unwrapped value. 
In both cases, the value of the whole expression is an optional value.

オプションの値を使って作業するときは? メソッド、プロパティ、およびサブスクリプトのような操作の前に。
?の前の値が? 無名:すべての後に? は無視され、式全体の値はnilになります。
  それ以外の場合、オプションの値はラップされず、? ラップされていない値に作用します。
どちらの場合も、式全体の値はオプションの値です。
let optionalSquare: Square? = Square(sideLength: 2.5, name: "optional square")
let sideLength = optionalSquare?.sideLength

以下が実行結果となります

Optional(2.5)

長くなりましたが続きは次回書きます。