ぜのぜ

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

39日目 Subscripts

日記

今日は酒を飲んで気持ちがいい

今日書いたコード

struct TimesTable {
    let multiplier: Int
    subscript(index: Int) -> Int {
        return multiplier * index
    }
}
let threeTimesTable = TimesTable(multiplier: 3)
print("six times three is \(threeTimesTable[6])")

struct Some {
    subscript(table: TimesTable) -> Int {
        return table.multiplier
    }
}
Some()[threeTimesTable]

初めて知ったこと

subscriptを初めて実装した.勝手にIntを使うものだと思ってたけど何でもいいらしい.

38日目 2ヶ月遅れの5月病

日記

最近何にもモチベがわかなくて良くない.遅めの5月病というか中だるみ感がすごい.

今日書いたコード

struct LevelTracker {
    static var highestUnlockedLevel = 1
    var currentLevel = 1

    static func unlock(_ level: Int) {
        if level > highestUnlockedLevel { highestUnlockedLevel = level }
    }

    static func isUnlocked(_ level: Int) -> Bool {
        return level <= highestUnlockedLevel
    }

    @discardableResult
    mutating func advance(to level: Int) -> Bool {
        if LevelTracker.isUnlocked(level) {
            currentLevel = level
            return true
        } else {
            return false
        }
    }
}

class Player {
    var tracker = LevelTracker()
    let playerName: String

    func complete(level: Int) {
        LevelTracker.unlock(level + 1)
        tracker.advance(to: level + 1)
    }

    init(name: String) {
        playerName = name
    }
}

var player = Player(name: "Argyrios")
player.complete(level: 1)
print("highest unlocked level is now \(LevelTracker.highestUnlockedLevel)")
// Prints "highest unlocked level is now 2"

player = Player(name: "Beto")
if player.tracker.advance(to: 6) {
    print("player is now on level 6")
} else {
    print("level 6 hasn't yet been unlocked")
}
// Prints "level 6 hasn't yet been unlocked"

初めて知ったこと

@discardableResult初めて使った.Methodsの章は今日で終わりだがだいたい知っていた気がする.

36日目

日記

ひぐらしのなく頃にの「頃」は夏なのか夕方なのか気になった.

今日書いたコード

class SomeClass {
    static var storedTypeProperty = "Some value."
//    class var overrideableStoredTypeProperty = "Some value."
    static var computedTypeProperty: Int {
        return 27
    }
    class var overrideableComputedTypeProperty: Int {
        return 107
    }
}

class SubClass: SomeClass {
    override static var overrideableComputedTypeProperty: Int {
        2
    }
}

class SubSubClass: SubClass {
//    SubClassでstatic varとなっているのでこれはできない
//    override static var overrideableComputedTypeProperty: Int {
//        2
//    }
}
print(SubClass.overrideableComputedTypeProperty) // => 2

初めて知ったこと

classの中のtype propertyのうちcomputed propertyはstaticではなくclassを使うことでサブクラスでoverrideすることができる.

35日目 projected value

日記

ご飯ができたので雑

今日書いたコード

@propertyWrapper
struct SmallNumber {
    private var number = 0
    var projectedValue = false
    var wrappedValue: Int {
        get { return number }
        set {
            if newValue > 12 {
                number = 12
                projectedValue = true
            } else {
                number = newValue
                projectedValue = false
            }
        }
    }
}

enum Size {
    case small, large
}

struct SizedRectangle {
    @SmallNumber var height: Int
    @SmallNumber var width: Int

    mutating func resize(to size: Size) -> Bool {
        switch size {
        case .small:
            height = 10
            width = 20
        case .large:
            height = 100
            width = 100
        }
        return $height || $width
    }
}

var sized = SizedRectangle()
print(sized.resize(to: .large), sized.$width, sized.$height)
print(sized.resize(to: .small), sized.$width, sized.$height)
// => true true true
// => true true false

初めて知ったこと

property wrapperはprojected valueを定義することで追加の機能を提供できる.上のコードの$で始まるやつ.SwiftUIでやたら便利なやつの意味がわかった.これどっちが先なんだろう.

34日目 property wrapper

日記

アマプラでカイジを見ていたら忘れるところだった

今日書いたコード

@propertyWrapper
struct TwelveOrLess {
    private var number = 0
    var wrappedValue: Int {
        get { return number }
        set { number = min(newValue, 12) }
    }
}

struct SmallRectangle {
    @TwelveOrLess var height: Int
    @TwelveOrLess var width: Int
}

var rectangle = SmallRectangle()
print(rectangle.height)
// Prints "0"

rectangle.height = 10
print(rectangle.height)
// Prints "10"

rectangle.height = 24
print(rectangle.height)
// Prints "12"

@propertyWrapper
struct SmallNumber {
    private var maximum: Int
    private var number: Int

    var wrappedValue: Int {
        get { return number }
        set { number = min(newValue, maximum) }
    }

    init() {
        maximum = 12
        number = 0
    }
    init(wrappedValue: Int) {
        maximum = 12
        number = min(wrappedValue, maximum)
    }
    init(wrappedValue: Int, maximum: Int) {
        self.maximum = maximum
        number = min(wrappedValue, maximum)
    }
}

struct NarrowRectangle {
    @SmallNumber(wrappedValue: 2, maximum: 5) var height: Int
    @SmallNumber(wrappedValue: 3, maximum: 4) var width: Int
}

var narrowRectangle = NarrowRectangle()
print(narrowRectangle.height, narrowRectangle.width)
// Prints "2 3"

narrowRectangle.height = 100
narrowRectangle.width = 100
print(narrowRectangle.height, narrowRectangle.width)
// Prints "5 4"

初めて知ったこと

property wrapperが何なのか初めて知った.今はそんなにSwiftUIを書いていないのでおまじない程度に思っていたがなるほどという感じ.これでいろいろあるproperty wrapperの理解が楽になりそうだと思った.

33日目 in-outパラメータのproperty observer

日記

今日はあまりに暇だったので明るいうちから書いている.

今日書いたコード

struct Cup {
    var content: String {
        willSet {
            print("willSet:", newValue)
        }
        didSet {
            print("didSet:", content)
        }
    }
}

func replace(_ newContet: String, from oldContent: inout String) {
    print("before pouring")
    oldContent = newContet
    print("after pouring")
}

func doNothing(_ content: inout String) {}

var coffeeCup = Cup(content: "")
print("call replace")
replace("coffee", from: &(coffeeCup.content))
print("call doNothing")
doNothing(&(coffeeCup.content))
// => call replace
// => before pouring
// => after pouring
// => willSet: coffee
// => didSet: coffee
// => call doNothing
// => willSet: coffee
// => didSet: coffee

初めて知ったこと

オブザーバを持つプロパティをin-outパラメータとして関数に渡すと,関数の最後でwillSetdidSetが呼ばれる.これはin-outパラメータについては関数の最後で値が書き戻されるようになっているため.そうなっている理由はIn-Out Parametersに書かれていそうなのでその時が来たら読む.

If you pass a property that has observers to a function as an in-out parameter, the willSet and didSet observers are always called. This is because of the copy-in copy-out memory model for in-out parameters: The value is always written back to the property at the end of the function. For a detailed discussion of the behavior of in-out parameters, see In-Out Parameters. https://docs.swift.org/swift-book/LanguageGuide/Properties.html