0Pricing
Scala for Backend Engineering & Functional Programming · レッスン

暗黙のパラメーター

コンテキストを渡します。

「暗黙のパラメーター」はCoddyKit上の無料Scala for Backend Engineering & Functional Programmingレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはScala for Backend Engineering & Functional Programming学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Scala for Backend Engineering & Functional Programmingコースには全4レッスンが含まれています。

コンテキストを自動的に渡す

暗黙のパラメーターを使うと、スコープ内でimplicitとマークされた値から、コンパイラーが引数を自動的に補ってくれます。設定や書式ルールなどの「周辺コンテキスト」を渡すのに適しています。

object Main {
  def greet(name: String)(implicit greeting: String): String =
    s"$greeting, $name!"
  implicit val defaultGreeting: String = "Hello"
  def main(args: Array[String]): Unit = {
    println(greet("Ann"))
  }
}

暗黙のパラメーターリスト

最後のパラメーターリストをimplicitキーワードでマークします。呼び出し側でその指定を省略すると、コンパイラーが一致する暗黙の値を検索します。

object Main {
  def multiply(x: Int)(implicit factor: Int): Int = x * factor
  implicit val f: Int = 10
  def main(args: Array[String]): Unit = {
    println(multiply(5))
  }
}

暗黙のパラメーターを明示的に渡す

暗黙のパラメーターはいつでも明示的に渡して、スコープ内の値を上書きできます。単発のケースで便利です。

object Main {
  def multiply(x: Int)(implicit factor: Int): Int = x * factor
  implicit val f: Int = 10
  def main(args: Array[String]): Unit = {
    println(multiply(5))
    println(multiply(5)(2))
  }
}

型による暗黙の解決

コンパイラーは名前ではなく型によって暗黙の値を照合します。スコープ内に一致する暗黙の値がちょうど1つ存在する必要があり、複数ある場合や存在しない場合はコンパイルに失敗します。

object Main {
  case class Config(env: String)
  def run()(implicit cfg: Config): String = s"running in ${cfg.env}"
  implicit val cfg: Config = Config("prod")
  def main(args: Array[String]): Unit = {
    println(run())
  }
}

implicitlyで値を取得する

implicitly[T]ヘルパーを使うと、パラメーター名を指定せずに、スコープから型Tの暗黙の値を直接取得できます。

object Main {
  implicit val name: String = "Scala"
  def main(args: Array[String]): Unit = {
    val n = implicitly[String]
    println(n)
  }
}

コンテキスト境界の省略記法

コンテキスト境界[T: Ordering]は、型Ordering[T]の暗黙のパラメーターを表す糖衣構文です。型クラスとともによく使われます。

object Main {
  def max[T: Ordering](a: T, b: T): T = {
    val ord = implicitly[Ordering[T]]
    if (ord.gt(a, b)) a else b
  }
  def main(args: Array[String]): Unit = {
    println(max(3, 7))
    println(max("apple", "pear"))
  }
}

呼び出しを通じてコンテキストを渡す

多くの関数が同じコンテキストを必要とする場合、暗黙のパラメーターが力を発揮します。一度implicitとしてマークすれば、ネストした呼び出しにも自動的に引き継がれます。

object Main {
  case class User(name: String)
  def log(msg: String)(implicit u: User): Unit =
    println(s"[${u.name}] $msg")
  def doWork()(implicit u: User): Unit = {
    log("started")
    log("finished")
  }
  implicit val current: User = User("admin")
  def main(args: Array[String]): Unit = {
    doWork()
  }
}

暗黙の値が検索される場所

コンパイラーは、ローカルスコープ、インポート、および関係する型のコンパニオンオブジェクトから暗黙の値を探します。デフォルト値を提供する場所として、コンパニオンオブジェクトは整理しやすい選択肢です。

object Main {
  case class Currency(symbol: String)
  object Currency {
    implicit val default: Currency = Currency("$")
  }
  def price(amount: Int)(implicit c: Currency): String = s"${c.symbol}$amount"
  def main(args: Array[String]): Unit = {
    println(price(50))
  }
}

曖昧性エラー

同じ型の暗黙の値が2つスコープ内にあると、コンパイラーは曖昧な暗黙の値に関するエラーを報告します。型ごとに最大1つにするか、明示的に渡してください。

object Main {
  def label(x: Int)(implicit unit: String): String = s"$x$unit"
  implicit val unit: String = "px"
  def main(args: Array[String]): Unit = {
    // Only one implicit String in scope -> no ambiguity
    println(label(12))
  }
}

デフォルトに似た動作

暗黙のパラメーターを使うと、コンテキストに応じたデフォルト値のように動作させられます。同じ関数呼び出しでも、スコープ内の暗黙の値によって結果が変わります。

object Main {
  def format(n: Double)(implicit decimals: Int): String =
    f"$n%.${decimals}f"
  implicit val d: Int = 2
  def main(args: Array[String]): Unit = {
    println(format(3.14159))
    println(format(3.14159)(4))
  }
}

暗黙の値は控えめに使う

暗黙のパラメーターは強力ですが、使いすぎるとコードを追いにくくなります。実行コンテキスト、設定、型クラスのインスタンスなど、本当に横断的なコンテキストに限って使用してください。

object Main {
  case class Locale(code: String)
  def hello()(implicit loc: Locale): String =
    if (loc.code == "tr") "Merhaba" else "Hello"
  implicit val loc: Locale = Locale("tr")
  def main(args: Array[String]): Unit = {
    println(hello())
  }
}

クイックチェック

コンパイラーは、暗黙のパラメーターに渡す値をどのように決定しますか。

まとめ

暗黙のパラメーター(Scala 2スタイル)について学びました。

  • パラメーターリストをimplicitでマークすると、自動的に値が補われます
  • 解決は型によって行われ、スコープ内で一意である必要があります
  • implicitly[T]は値を取得し、コンテキスト境界[T: TC]はその糖衣構文です
  • ローカルスコープ、インポート、コンパニオンオブジェクトが検索されます
  • すべてに使うのではなく、横断的なコンテキストに使用します

よくある質問

「暗黙のパラメーター」レッスンは無料ですか?

はい。「暗黙のパラメーター」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Scala for Backend Engineering & Functional Programmingコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Scala for Backend Engineering & Functional Programmingコースには全4レッスンが含まれています。

「暗黙のパラメーター」で何を学びますか?

コンテキストを渡します。 ブラウザで直接実行するハンズオンコードでScala for Backend Engineering & Functional Programmingを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Scala for Backend Engineering & Functional Programmingを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのScala for Backend Engineering & Functional Programmingは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。

「暗黙のパラメーター」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このScala for Backend Engineering & Functional Programmingレッスンでコードを書いて実行できますか?

はい。すべてのScala for Backend Engineering & Functional Programmingレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 暗黙のパラメーター
  2. Scala 3 の given/using
  3. 暗黙の変換
  4. 拡張メソッド
← Scala for Backend Engineering & Functional Programmingに戻る