2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[Swift] このコードは書かないでください!(代わりに幽霊型を使いましょう)

Last updated at Posted at 2023-11-11

前提

上記Youtubeを日本語でざっくり解説します。
※あくまでも私のアウトプットなので間違っていたらご教授いただけますと幸いです。

どのような内容か

以下は、コンパイルエラーが発生しないコードです。

import Foundation

struct Person {
    let id = UUID()
    let name: String
}

struct Location {
    let id = UUID()
    let coordinates: (Double, Double)
}

func handle(locations: [Location]) {
    let me = Person(name: "Test")
    let filtered = locations.filter { $0.id == me.id }
}

以下は、コンパイルエラーが発生するコードです。

import Foundation

struct ID<T>: Equatable {
    private let value = UUID()
}

struct Person {
    let id = ID<Self>()
    let name: String
}

struct Location {
    let id = ID<Self>()
    let coordinates: (Double, Double)
}

func handle(locations: [Location]) {
    let me = Person(name: "Test")
    let filtered = locations.filter { $0.id == me.id } // ここでエラー
} 
Cannot convert value of type 'ID<Person>' to expected argument type 'ID<Location>'

ここで伝えておきたいことは、今回の動画では コンパイルエラーが発生しないことが問題(ダメ)だよ ってことだと思います。

なぜコンパイルエラーが発生しないことに問題があるのか

以下は先程のコンパイルエラーが発生しないコードと同様

import Foundation

struct Person {
    let id = UUID()
    let name: String
}

struct Location {
    let id = UUID()
    let coordinates: (Double, Double)
}

func handle(locations: [Location]) {
    let me = Person(name: "Test")
    let filtered = locations.filter { $0.id == me.id } // ココに問題がある
}

Swiftでは、異なる型同士での比較はしてはいけません。

簡単に言うと、以下は比較できませんよね。

let int = 0
let string = "0"

if int == string { 

}
// 以下はエラー内容
// Binary operator '==' cannot be applied to operands of type 'Int' and 'String'

この決まりがある中で、コンパイルエラーにならなかったコードの以下の部分は、型が違うのにコンパイルエラーが出ていません。

{ $0.id == me.id } // $0は、Location型。 meは、Person型。

// なぜコンパイルエラーにならないのか
// コンパイルするときに$0とmeの型は違うけど、どちらのidもUUID型だから比較OKになってしまう。

これは予測できない動作を引き起こす可能性が出てきてしまうので、今回の動画ではこのコードは書かないでください!ってことになっている。と思われます!

だから、エラーが発生する方のコードのようにして、異なる型同士の比較をできないようにコンパイルエラーを出してくれるようにしよう!

といった感じです。

最後に

エラーが発生する方のコードのようにして、異なる型同士の比較をできないようにコンパイルエラーを出してくれるようにしよう!

先程の引用で上記のようにコンパイルエラーを出すようにすることを幽霊型というらしい。

詳しくは以下を参考

2
3
4

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
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?