[解決済み] Scalaの識別子 "implicitly "とは?
質問
という名前の関数を見たことがあります。
implicitly
Scala のサンプルで使用されています。これは何ですか、そしてどのように使用されていますか?
サンプルはこちら :
scala> sealed trait Foo[T] { def apply(list : List[T]) : Unit }; object Foo {
| implicit def stringImpl = new Foo[String] {
| def apply(list : List[String]) = println("String")
| }
| implicit def intImpl = new Foo[Int] {
| def apply(list : List[Int]) = println("Int")
| }
| } ; def foo[A : Foo](x : List[A]) = implicitly[Foo[A]].apply(x)
defined trait Foo
defined module Foo
foo: [A](x: List[A])(implicit evidence$1: Foo[A])Unit
scala> foo(1)
<console>:8: error: type mismatch;
found : Int(1)
required: List[?]
foo(1)
^
scala> foo(List(1,2,3))
Int
scala> foo(List("a","b","c"))
String
scala> foo(List(1.0))
<console>:8: error: could not find implicit value for evidence parameter of type
Foo[Double]
foo(List(1.0))
^
を書かなければならないことに注意してください。
implicitly[Foo[A]].apply(x)
というのは、コンパイラは
implicitly[Foo[A]](x)
を呼び出すことを意味します。
implicitly
をパラメータで指定します。
また、以下を参照してください。 Scala REPLからオブジェクト/タイプ/その他を調査する方法は? と Scala はどこでインプリシットを探すのですか?
どのように解決するのですか?
以下は、Delightly Simple Methodを使用する理由です。
implicitly
.
暗黙のビューを理解するために/トラブルシューティングするために
Implicit Viewは、選択項目の接頭辞(例えば、以下のようなものを考えてみてください)があるときに起動することができます。
the.prefix.selection(args)
が含まれていない場合
selection
に適用される
args
(を変換してみても)。
args
を暗黙のビューで表示します)。この場合、コンパイラは、現在のスコープまたはそれを囲むスコープでローカルに定義された暗黙のメンバ、継承された、またはインポートされたメンバを探します。
the.prefix
を持つ型に
selection
が定義されている場合、または同等の暗黙のメソッドが定義されている場合です。
scala> 1.min(2) // Int doesn't have min defined, where did that come from?
res21: Int = 1
scala> implicitly[Int => { def min(i: Int): Any }]
res22: (Int) => AnyRef{def min(i: Int): Any} = <function1>
scala> res22(1) //
res23: AnyRef{def min(i: Int): Int} = 1
scala> .getClass
res24: java.lang.Class[_] = class scala.runtime.RichInt
暗黙のViewは、以下のように、式がExpected Typeに適合しない場合にも発生します。
scala> 1: scala.runtime.RichInt
res25: scala.runtime.RichInt = 1
ここで、コンパイラはこの関数を探します。
scala> implicitly[Int => scala.runtime.RichInt]
res26: (Int) => scala.runtime.RichInt = <function1>
コンテキストバウンドによって導入された暗黙のパラメータにアクセスする
暗黙のパラメータは、暗黙のViewよりも重要なScalaの機能だと言えるでしょう。これは型クラスパターンをサポートします。標準ライブラリはこれを数カ所で使っています。
scala.Ordering
でどのように使用されているか、また
SeqLike#sorted
. 暗黙のパラメータは、Array マニフェストの受け渡しにも使用されます。
CanBuildFrom
のインスタンスです。
Scala 2.8では、コンテキストバウンズと呼ばれる暗黙のパラメータの略記構文が使用できます。簡単に説明すると,型パラメタ
A
型の暗黙のパラメータを必要とする
M[A]
:
def foo[A](implicit ma: M[A])
は次のように書き換えることができる。
def foo[A: M]
しかし、暗黙のパラメータを渡すのに名前をつけないというのはどういうことでしょうか?メソッドを実装するときに、これがどのように役に立つのでしょうか?
foo
?
多くの場合、暗黙のパラメータは直接参照される必要はなく、呼び出される別のメソッドの暗黙の引数としてトンネルされることになります。もしそれが必要なら、Context Boundで簡潔なメソッドシグネチャを保持したまま、次のように呼び出すことができます。
implicitly
を使用して、値を実体化する。
def foo[A: M] = {
val ma = implicitly[M[A]]
}
暗黙のパラメータのサブセットを明示的に渡す
型クラスベースのアプローチで、人物をきれいに印刷するメソッドを呼び出すとします。
trait Show[T] { def show(t: T): String }
object Show {
implicit def IntShow: Show[Int] = new Show[Int] { def show(i: Int) = i.toString }
implicit def StringShow: Show[String] = new Show[String] { def show(s: String) = s }
def ShoutyStringShow: Show[String] = new Show[String] { def show(s: String) = s.toUpperCase }
}
case class Person(name: String, age: Int)
object Person {
implicit def PersonShow(implicit si: Show[Int], ss: Show[String]): Show[Person] = new Show[Person] {
def show(p: Person) = "Person(name=" + ss.show(p.name) + ", age=" + si.show(p.age) + ")"
}
}
val p = Person("bob", 25)
implicitly[Show[Person]].show(p)
名前の出力方法を変更したい場合はどうすればよいでしょうか。その場合は、明示的に
PersonShow
を渡すか、明示的に代替の
Show[String]
を渡すようにしたい。
Show[Int]
.
Person.PersonShow(si = implicitly, ss = Show.ShoutyStringShow).show(p)
関連
-
[解決済み] Scalaでステートメントの間にN秒待つには?
-
[解決済み] Scalaでswitch/case(単純なパターンマッチ)を使うには?
-
[解決済み] Seq[Future[Person]]ではなく、Future[Seq[Person]]を取得する方法
-
[解決済み] A の値をキーとして Seq[A] を Map[Int, A] に変換する方法は?
-
[解決済み] 理解する `andThen`
-
[解決済み] ScalaのDSLって何?[クローズド]
-
[解決済み】Scalaにおける中括弧と括弧の正式な違い、また、どのような場合に使用すべきなのか?
-
[解決済み】Scalaのvarとvalの定義の違いは何ですか?
-
[解決済み】Scalaのコンテキストとビューバウンドとは何ですか?
-
[解決済み】Scalaはどこでimplicitを探すのか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Scala forallの例?
-
[解決済み] AWSのためのScala SDKまたはインターフェースはありますか?
-
[解決済み] sparkでrddオブジェクトをdataframeに変換する方法
-
[解決済み】Scala 2.8 breakOut
-
[解決済み】ScalaでVectorを選択するのはどんなとき?
-
[解決済み】Scalaのウェブフレームワークは何がありますか?[クローズド]
-
[解決済み】レイジーバルって何するもの?
-
[解決済み】Scalaの名前による呼び出しと値による呼び出し、明確化の必要性
-
[解決済み] sbtのScalaTest:タグなしで単一のテストを実行する方法はありますか?
-
[解決済み】Scalaはどこでimplicitを探すのか?