0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Swift カスタム型のイニシャライザにオプショナル型を含める際のメモ

Posted at

カスタム型のイニシャライザの気づきが合ったのでメモ

イニシャライザをたくさん用意して最低限でもインスタンス生成できるように工夫していた。
メソッドの引数にデフォルト引数を定義することで、イニシャライザを含めメソッドの多重定義より見通しが良くなることに気づいたので、記事にしました。(みんなはすぐ気がついていたはず)

イニシャライザにオプショナル型を含める場合

オプショナル型のプロパティをイニシャライザに含める場合
定義はnameはString型、ageはInt?型と仮定すると、こうなる

struct Human:Codable,Equatable, Hashable{
    var name: String
    var age: Int?

    init(name: String,
         age: Int? = nil
    ) {
        self.name = name
        self.age = age
    }
}

インスタンスは、ageがあってもなくてもいい。

Human(name:"太郎",age:40)
Human(name:"花子")

でも、こう書いてもいい。イニシャライザを引数ごとに複数用意する。

struct Human:Codable,Equatable, Hashable{
    var name: String
    var age: Int?

    //引数が明確な値のみ代入することを明記する
    init(name: String
    ) {
        self.name = name
    }
    //オプショナル型の引数はインスタンス生成時に入力するか選べる
    init(name: String,
         age: Int? = nil
    ) {
        self.name = name
        self.age = age
    }
}

使い分けについての個人的意見

あくまで個人の意見であり、使ってみた感想に過ぎません。
オプショナル型の場合、デフォルトで引数nilを渡す呼び出しがいいのか?
多重定義が良いのか?

わざわざ言い立てるほどでもない気がするけど、こうやって記事にでもしないと記憶に定着しないからこうして記事にしている。

使い分けのミソがイマイチわからない。
どっちでもいいんじゃないか。
ただ確実に前者のほうがコード量が少なくて、後々プロパティを増やす減らすなど対処ができたときに出戻りが少ない。
チームで開発する場合、設計が定まってから行うことがほとんどだと思われるので、前者のみを採用するのがいいと思った。
しかし、個人で開発する場合においては、後者でいくつも多重定義しておいて、設計が定まってきた段階で、前者に切り替えるのが良いかなと思った。
一方で、複数のイニシャライザが用意されていたほうが、オプショナル型への気付きがしやすい気もした。
感想は以上です。

BookMarkInfo.swift
struct BookMarkInfo:Codable,Equatable, Hashable{
    var title: String
    var description: String
    var urlString: String
    var iconUrlString:String?
    var iconData:Data?

    init(title: String,
         description: String,
         urlString: String,
         iconUrlString: String? = nil,
         iconData:Data? = nil
    ) {
        self.title = title
        self.description = description
        self.urlString = urlString
        self.iconUrlString = iconUrlString
        self.iconData = iconData
    }
}

気づいたきっかけ

Swiftのドキュメントを読んでいても、デフォルト引数というのがメジャーなのかなと感じた。
例えば、resizableモデファイはデフォルトでcapInsets及びresizingModeの引数を渡しているので、呼び出すときはresizingMode()だけで成立してしまう。

    public func resizable(capInsets: EdgeInsets = EdgeInsets(), resizingMode: Image.ResizingMode = .stretch) -> Image

疑問に感じたこと

この場合だと、frame()では、widthとheightがnilになってしまうと思った。

@inlinable nonisolated public func frame(width: CGFloat? = nil, height: CGFloat? = nil, alignment: Alignment = .center) -> some View

しかし、frameはだいたいコード書いている人が必要な値を埋め込むもしくは周りの成約でサイズは流動的に変わるからいいのかな。

内容がスカスカですが以上です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?