ぜのぜ

しりとりしようぜのぜのぜのぜ

32日目 lazy var

日記

久々に湯船浸かるかーと思ったら排水口にお湯を捨てていた.仕方がないのでシャワーだけ浴びてビール飲みながら書いてる.

今日書いたコード

class DataImporter {
    var filename = "data.txt"

    init() {
        print("Initialize DataImporter")
    }
}

class DataManager {
    lazy var importer = DataImporter()
    var data: [String] = []
}

let manager = DataManager()
print("Add Some data")
manager.data.append("Some data")
print("Add Some more data")
manager.data.append("Some more data")
print("Add Some data")
print(manager.importer.filename)

実行結果

Add Some data
Add Some more data
Add Some data
Initialize DataImporter
data.txt

初めて知ったこと

まだ初期化されていないlazyなプロパティが複数のスレッドから同時にアクセスされたとき,1度だけ初期化されることは保証されない

If a property marked with the lazy modifier is accessed by multiple threads simultaneously and the property hasn’t yet been initialized, there’s no guarantee that the property will be initialized only once. https://docs.swift.org/swift-book/LanguageGuide/Properties.html

このコードを実行すると,

import Foundation

class DataImporter {
    var filename = "data.txt"

    init() {
        print("Initialize DataImporter")
    }
}

class DataManager {
    lazy var importer = DataImporter()
    var data: [String] = []
}

let someManager = DataManager()
DispatchQueue.init(label: "first").async {
    print("first")
    someManager.importer.filename
}
DispatchQueue.init(label: "second").async {
    print("second")
    someManager.importer.filename
}

何回かに1回は以下のような出力が得られる.

second
first
Initialize DataImporter
Initialize DataImporter

31日目

日記

カレーが呼んでいるのでサクッと書いた.おわり

今日書いたコード

struct Resolution {
    var width = 0
    var height = 0
}
class VideoMode {
    var resolution = Resolution()
    var interlaced = false
    var frameRate = 0.0
    var name: String?
}

let hd = Resolution(width: 1920, height: 1080)
let tenEighty = VideoMode()
tenEighty.resolution = hd
tenEighty.interlaced = true
tenEighty.name = "1080i"
tenEighty.frameRate = 25.0

let alsoTenEighty = tenEighty
alsoTenEighty.frameRate = 30.0

print("The frameRate property of tenEighty is now \(tenEighty.frameRate)") // => Prints "The frameRate property of tenEighty is now 30.0"

初めて知ったこと

ポインタとバッファを扱う型があるらしい

The standard library provides pointer and buffer types that you can use if you need to interact with pointers directly—see Manual Memory Management.

https://docs.swift.org/swift-book/LanguageGuide/ClassesAndStructures.html

30日目

日記

テレビを見ていたらチャーハンの話をしていたのでチャーハンを作った.

今日書いたコード

struct Some {
    var va: Int
    var vb: Int = 0
    var vc: Int?
    let la: Int
    let lb: Int = 0
    let lc: Int?
}

Some(va: 0, la: 0, lc: 0) // コンパイルできる最小の引数

初めて知ったこと

varで定義したオプショナルなプロパティはnilで初期化されて,letで定義されたそれは暗黙的に初期化されない.

29日目 FizzBuzz

日記

最近ロシア語を喋りたくなってきたのでロシア語コンテンツをYouTubeで観てるんだけど,聞き取れるようになる気がしない.何で俺は英語がある程度聞き取れるのかめちゃくちゃ不思議.やっぱ義務教育ってすごいんですね.

今日書いたコード

今日は何もやる気が出なかったのでFizzBuzzを書いた.

❯ echo -n '(1...100).map{($0 % 3==0 ?"fizz":($0 % 5==0 ?"":"\($0)"))+($0 % 5==0 ?"buzz":"")}' | wc -m
      81

言語化できたレギュレーションは以下の通り

  • let actual =以降の文字列を最小化する
  • playground上で走らせられる
  • check(_ actual:)assertで落ちない
func check(_ actual: [String]) {
    var expected: [String] = []
    for i in 1...100 {
        let tmp: String = {
            if i % 3 == 0 {
                return i % 5 == 0 ? "fizzbuzz" : "fizz"
            } else  if i % 5 == 0 {
                return "buzz"
            } else {
                return "\(i)"
            }
        }()
        expected.append(tmp)
    }

    for (e, a) in zip(expected, actual) {
        print(e, a, separator: " ")
    }

    assert(expected.elementsEqual(actual))
}

//let actual = (1...100).map {"\($0 % 3 == 0 ? "fizz" : ($0 % 5 != 0 ? "\($0)" : ""))\($0 % 5 == 0 ? "buzz" : "")" }
let actual = (1...100).map{($0 % 3==0 ?"fizz":($0 % 5==0 ?"":"\($0)"))+($0 % 5==0 ?"buzz":"")}
//let actual = (1...100).map {"\($0 % 3 == 0 ? "fizz" : ($0 % 5 != 0 ? "\($0)" : ""))\($0 % 5 == 0 ? "buzz" : "")" }

check(actual)

初めて知ったこと

🍐

28日目 Recursive Enumerations

日記

おやすみ

今日書いたコード

indirect enum ArithmeticExpression {
    case number(Int)
    case addition(ArithmeticExpression, ArithmeticExpression)
    case multiplication(ArithmeticExpression, ArithmeticExpression)
}

func evaluate(_ expression: ArithmeticExpression) -> Int {
    switch expression {
    case let .number(value):
        return value
    case let .addition(left, right):
        return evaluate(left) + evaluate(right)
    case let .multiplication(left, right):
        return evaluate(left) * evaluate(right)
    }
}

let five = ArithmeticExpression.number(5)
let four = ArithmeticExpression.number(4)
let sum = ArithmeticExpression.addition(five, four)
let product = ArithmeticExpression.multiplication(sum, ArithmeticExpression.number(2))
print(evaluate(product))

indirect enum BinTree {
    case inner(left: BinTree, right: BinTree, value: Int)
    case leaf(value: Int)
}

func inOrderTraverse(_ tree: BinTree) {
    switch tree {
    case let .inner(left, right, value):
        inOrderTraverse(left)
        print(value)
        inOrderTraverse(right)
    case let .leaf(value):
        print(value)
    }
}

let tree = BinTree.inner(
    left: .inner(
        left: .leaf(value: 0),
        right: .inner(
            left: .leaf(value: 2),
            right: .leaf(value: 4),
            value: 3),
        value: 1),
    right: .leaf(value: 6),
    value: 5)

inOrderTraverse(tree)
// =>
// 0
// 1
// 2
// 3
// 4
// 5
// 6

初めて知ったこと

Recursive Enumerationsというやつ.associated valueとして自分と同じ型の値を持つenumをこう呼ぶ.enumキーワードかcaseキーワードの前にindirectと書くことで宣言できる.再帰的な構造をもつデータを表すのに便利そう,というかそう書いてあった.

27日目

日記

最近YouTubeアゼルバイジャンのおじさんが料理するチャンネル(WILDERNESS COOKING)の動画を見ている.たまに生前の材料と笑顔のおじさんというサムネになっていてなかなか迫力がある.

今日書いたコード

今日からEnumerationsの章に入った.参照型のassociated valueをswitch内で変更すると外でも変更されるか確かめた.

enum Liquid {
    case vodka(Material)
    case water
}

class Material {
    var name: String

    init(_ name: String) {
        self.name = name
    }
}

let liquid = Liquid.vodka(Material("corn"))

switch liquid {
case .vodka(var material):
    material.name = "rye"
case .water:
    print("water")
}

if case .vodka(let material) = liquid {
    print(material.name) // => rye
}

初めて知ったこと

... most vodka today is produced from grains such as sorghum, corn, rye or wheat. Among grain vodkas, rye and wheat vodkas are generally considered superior. https://en.wikipedia.org/wiki/Vodka

26日目 Autoclosures

日記

ぬるぽ

今日書いたコード

var customersInLine = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]

func serve(customer customerProvider: @autoclosure () -> String) {
    print("Now serving \(customerProvider())!")
}
serve(customer: customersInLine.remove(at: 0))

初めて知ったこと

Autoclosures自体初めて知ったが使い所がわからない.標準ライブラリのassert(_ condition:,_ message:)はdebugビルドのときだけconditionが実行されるが,これはAuclosuresを使って実装されている.

public func assert(_ condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String = String(), file: StaticString = #file, line: UInt = #line)