質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

1521閲覧

antitypical/Resultについて

MasakiHori

総合スコア3384

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2018/01/31 02:13

編集2018/02/10 07:44

antitypical/Resultの型パラメータがなぜそのようになっているのか疑問に思ったので質問します。

antitypical/Resultでは Resultの定義は以下のようになっています。(必要部分のみ抜き出し)

swift

1enum Result<Value, Error: Swift.Error> { ... }

疑問に思ったのは以下の2点です。

######1. なぜ以下の定義ではないのか
~~enum Result<Value, Error> { … }~~~
Error: Swift.Errorとせずとも単にErrorとするだけで全く同じことになると思うのですが、
なぜError: Swift.Errorとしているのでしょか?

######2.そもそもErrorを型パラメータにする必要があるのか
Swiftの場合はErrorが既に定義されているので

swift

1enum Result<Value> { ... }

としても同等の事が実装出来ると思います。なぜErrorを型パラメータに含めているのでしょ。
こちらに関してはSwift以外の実装に合わせたのではないか、使用時にエラーの型を明示/限定できるようにではないか、とは思っていますが、ほかの理由があるのかが知りたいです。

以上、よろしくお願いします


追記

Swiftには標準でErrorという型があります。
そのため
~~
enum Result<Value, Error: Swift.Error> { // ErrorはSwift.Errorに制限される。
case value(Value)
case error(Error)
}
~~
としても
~~
enum Result<Value, Error> { // ErrorはSwift.Errorそのもの。
case value(Value)
case error(Error)
}
~~
としてもほとんど違いはなく、また

swift

1enum Result<Value> { 2 case value(Value) 3 case error(Error) // 型パラメータを持たずともError型を持てる 4}

としてもerrorは表現可能です。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

2の質問からお答えします。

そもそもErrorを型パラメータにする必要があるのか

これは関数型言語ならではのものでEither型というものです。
このワードでググルとたくさんの説明が出ると思います。

自分なりに説明すると、エラーとの戦い方の一つの選択肢です。

以下にエラー処理の手法と問題点をあげます

例外にしてそれをキャッチして処理するというやり方

Javaが採用している方法です。どこがエラー処理を行うかコードから読み取りづらいという問題を抱えています。
よく見ると思うので特に例は示しません

多値を返すやり方

Goが採用している点です。
上記Javaと違って必ずエラーハンドリングをしないといけないという状況になります。
それがメリットであり必ずエラーハンドリングをしないといけないのでどこがエラー処理をしているか追いやすいのです。

func something() (int, error) { if err := hogehoge(); err != nil { return -1,err } return 42, nil }

これの問題点はメソッドチェーンが作れないということです。
つまり返り値のメソッドを再度呼び出して処理を継続することができないのです。
必ずエラーを処理してから次のメソッドを呼び出すという縛りができます。

Eitherのやり方

おわかリでしょうか。上記2つの例のいいとこ取りしたのがResult<Value, Error>なのです。
エラー情報を含んだ一つの塊を返すのでメソッドチェーンで拾って次の処理に使ってもいいですし
そもそもエラーを含んでいるからメソッドチェーンの処理を中断してもいいです。

1の質問について

enum Result<Value, Error: Swift.Error> { ... }

なのは単にSwift.Errorを継承したError型に限定したいんでしょう。
エラーがSwift.Errorであることが保証できれば、エラー処理の時に必ず存在するメソッドかあるというメリットがあります

投稿2018/02/09 22:50

m0a

総合スコア708

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

MasakiHori

2018/02/10 07:37

SwiftでResultを表現する方法を追記しました。 Swiftには標準でErrorという型(protocol)が存在しています。(Javaで言うところのInterfaceのようなものです) Errorはprotocolですので実態はなく、使用者がErrorに準拠(継承)した実体を定義する必要がある。 その上で 1, わざわざSwift.Errorに準拠した新しいErrorを型パラメータとして持つ必要があるのか。 2, そもそもError自体を型パラメータとして持つ必要があるのか。 という質問です。
MasakiHori

2018/02/10 07:42

色々書いてたら1番目の問題は僕の勘違いであることがわかりましたので取り下げました。
m0a

2018/02/10 13:48

Result<Value> にしてしまうとその内部で使っているSwift.Errorに固定されてしまうことになります。 そこをMyErrorなどとして任意のメソッドを追加した自作のErrorを用意すれば 全体を通してMyErrorが使えることになります。 一々アップキャストして使いたくないですよね。
MasakiHori

2018/02/10 15:06

なるほどです。 理解できました。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問