型の相互変換
Option、Either、Try です。
「型の相互変換」はCoddyKit上の無料Scala for Backend Engineering & Functional Programmingレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはScala for Backend Engineering & Functional Programming学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Scala for Backend Engineering & Functional Programmingコースには全4レッスンが含まれています。
3 つのエラーモデル
Scala には、値の不在と失敗を表す相補的な 3 つの型があります。
Option— 存在または不在(理由はありません)。Either— 成功または型付きエラー。Try— 成功またはスローされた例外。
これらの間で変換する方法を知っていれば、ある API を別の API に適応させられます。
Option から Either へ
toRightはOptionをEitherに変換し、Noneの場合はLeftのエラーを指定します。toLeftは逆方向にマッピングします。
@main def run(): Unit = {
val some: Option[Int] = Some(5)
val none: Option[Int] = None
println(some.toRight("missing"))
println(none.toRight("missing"))
}EitherからOptionへ
toOptionはエラーを破棄します。Right(x)はSome(x)に、Left(_)はNoneになります。失敗の理由がもはや重要でない場合に使用します。
@main def run(): Unit = {
val r: Either[String, Int] = Right(42)
val l: Either[String, Int] = Left("err")
println(r.toOption)
println(l.toOption)
}TryからOptionへ
Try.toOptionはSuccessをSomeに、FailureをNoneに変換し、例外を握りつぶします。
import scala.util.Try
@main def run(): Unit = {
println(Try("7".toInt).toOption)
println(Try("x".toInt).toOption)
}TryからEitherへ
Try.toEitherはEither[Throwable, T]を生成します。SuccessはRightに、FailureはLeft(throwable)になります。これにより、例外を型付きのleftとして保持できます。
import scala.util.Try
@main def run(): Unit = {
val ok = Try("7".toInt).toEither
val no = Try("x".toInt).toEither
println(ok)
println(no.left.map(_.getMessage))
}EitherからTryへ
単純なエラーを持つEitherからTryへの直接的な組み込み変換はありませんが、自分で作成できます。RightをSuccessでラップし、Leftを例外を保持するFailureでラップします。
import scala.util.{Try, Success, Failure}
object Main {
def toTry(e: Either[String, Int]): Try[Int] = e match {
case Right(v) => Success(v)
case Left(m) => Failure(new RuntimeException(m))
}
def main(args: Array[String]): Unit = {
println(toTry(Right(1)))
println(toTry(Left("bad")))
}
}OptionからTryへ
空の場合に使用する例外を選ぶことで、OptionをTryに変換できます。APIがTryを要求する場合に便利です。
import scala.util.{Try, Success, Failure}
object Main {
def toTry[A](o: Option[A]): Try[A] = o match {
case Some(v) => Success(v)
case None => Failure(new NoSuchElementException("empty"))
}
def main(args: Array[String]): Unit = {
println(toTry(Some(9)))
println(toTry(None))
}
}パイプラインの正規化
型を混在させると扱いにくくなります。一般的な方法は、早い段階ですべてを統一されたエラー型のEitherに変換し、その後は自由に合成することです。
import scala.util.Try
object Main {
def parse(s: String): Either[String, Int] =
Try(s.toInt).toEither.left.map(_ => s"invalid: $s")
def lookup(n: Int): Either[String, String] =
Map(1 -> "one", 2 -> "two").get(n).toRight(s"no entry for $n")
def main(args: Array[String]): Unit = {
val result = for {
n <- parse("2")
w <- lookup(n)
} yield w
println(result)
}
}型をまたいだgetOrElse
3つの型はいずれも、getOrElseで値を取り出すか、デフォルト値を指定できます。これは多くの場合、エラー処理の世界から抜ける最後のステップです。
import scala.util.Try
@main def run(): Unit = {
val a = Some(1).getOrElse(0)
val b = (Right(2): Either[String, Int]).getOrElse(0)
val c = Try("x".toInt).getOrElse(0)
println(s"$a $b $c")
}適切な型の選択
指針:
- 不在について説明が不要な場合はOptionを使用します。
- ドメイン固有のエラー値が必要な場合はEitherを使用します。
- 例外をスローするJavaやライブラリのコードとの境界ではTryを使用します。
エンドツーエンドの例
例外をスローするコードをTryで読み取り、ドメインエラーを扱うためにEitherへ変換し、最後に存在するかどうかだけを気にする呼び出し元のためにOptionへ変換します。
import scala.util.Try
object Main {
def safeDiv(a: Int, b: Int): Option[Int] =
Try(a / b).toEither.left.map(_ => "math error").toOption
def main(args: Array[String]): Unit = {
println(safeDiv(10, 2))
println(safeDiv(10, 0))
}
}理解度チェック
変換に関する知識を確認しましょう。
まとめ
Option、Either、Tryの相互変換について学びました。
Option.toRight→ Either、Either.toOption→ Option。Try.toOptionとTry.toEitherは、例外を値へ橋渡しします。- パイプラインは早い段階で1つのエラー型に正規化します。
- 必要なエラー情報の量に合った型を選びます。
よくある質問
「型の相互変換」レッスンは無料ですか?
はい。「型の相互変換」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Scala for Backend Engineering & Functional Programmingコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Scala for Backend Engineering & Functional Programmingコースには全4レッスンが含まれています。
「型の相互変換」で何を学びますか?
Option、Either、Try です。 ブラウザで直接実行するハンズオンコードでScala for Backend Engineering & Functional Programmingを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Scala for Backend Engineering & Functional Programmingを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのScala for Backend Engineering & Functional Programmingは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「型の相互変換」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このScala for Backend Engineering & Functional Programmingレッスンでコードを書いて実行できますか?
はい。すべてのScala for Backend Engineering & Functional Programmingレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。