복붙노트

[SCALA] "암시"스칼라 ID는 무엇입니까?

SCALA

"암시"스칼라 ID는 무엇입니까?

나는 암시라는 이름의 스칼라 예에서 사용하는 함수를 보았다. 그것은 무엇이고, 어떻게 사용됩니까?

여기 예 :

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))
          ^

우리가 암시 적으로 작성해야합니다 [푸 [A]]. 적용 (x)는 컴파일러가 암시 적으로 [푸 [A] (x)를 우리는 매개 변수를 암시 적으로 호출한다는 것을 의미 있다고 생각하기 때문이다.

또한 등 / 개체 / 유형을 조사하는 방법을 참조하십시오. 스칼라 REPL에서? 및 그 스칼라 implicits 찾아합니까?

해결법

  1. ==============================

    1.여기에 암시 적으로 쾌적 간단한 방법을 사용하는 몇 가지 이유가 있습니다.

    여기에 암시 적으로 쾌적 간단한 방법을 사용하는 몇 가지 이유가 있습니다.

    암시보기가 선택의 접두사 (예를 들어 고려할 때 트리거 될 수 있습니다, the.prefix.selection (인수)이있다. 심지어 암시 조회수와 인수를 변환하려고 후 인수 (에 적용 할 수있는 멤버 선택)를 포함하지 않는 경우, 컴파일러는 정의 된 선택과 유형, 또는 이에 상응하는 암시 적 방법에 그 the.prefix의 종류에서 하나의 기능은 그 로컬, 현재 또는 둘러싸 범위에 정의 된 상속, 또는 수입 암시 회원을 찾습니다.

    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
    

    표현은 다음과 같이 예상 유형과 일치하지 않는 경우 암시보기도 트리거 될 수 있습니다 :

    scala> 1: scala.runtime.RichInt
    res25: scala.runtime.RichInt = 1
    

    여기에 컴파일러는이 기능을 찾습니다

    scala> implicitly[Int => scala.runtime.RichInt]
    res26: (Int) => scala.runtime.RichInt = <function1>
    

    암시 적 매개 변수는 틀림없이 암시보기보다는 스칼라의 더 중요한 기능입니다. 그들은 유형 클래스 패턴을 지원합니다. scala.Ordering을보고이 SeqLike 번호에서 어떻게 사용되는지 정렬 - 표준 라이브러리는 몇 군데에서 이것을 사용합니다. 암시 적 매개 변수는 배열 매니페스트 및 CanBuildFrom 인스턴스를 전달하는 데 사용된다.

    스칼라 2.8 문맥 경계라는 암시 적 매개 변수에 대한 약식 구문을 할 수 있습니다. 간단히 입력 내재적 파라미터를 필요로하는 종류의 파라미터 A의 방법 M [A] :

    def foo[A](implicit ma: M[A])
    

    로 다시 작성할 수 있습니다 :

    def foo[A: M]
    

    그러나 암시 적 매개 변수를 전달하지만 이름을 지정하지 않는 점은 무엇인가? 메소드 foo는 구현할 때 어떻게 이런 일이 유용 할 수있다?

    종종, 암시 적 매개 변수를 직접 호출 될 때 다른 방법에 대한 암시 적 인수로를 통해 터널링 될 것입니다 언급 할 필요가 없다. 이 필요한 경우, 당신은 여전히 ​​바인딩 컨텍스트와 간결한 방법 서명을 유지하고 가치를 실현하기 위해 암시 적으로 호출 할 수 있습니다 :

    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를 호출 대안 쇼 [문자열]을 통과하지만, 우리는 컴파일러가보기 [지능]을 통과 할 수 있습니다.

    Person.PersonShow(si = implicitly, ss = Show.ShoutyStringShow).show(p)
    
  2. ==============================

    2.암시 스칼라 2.8 드라마이며 PREDEF 같이 정의된다 :

    암시 스칼라 2.8 드라마이며 PREDEF 같이 정의된다 :

    def implicitly[T](implicit e: T): T = e
    

    일반적으로 T 형의 내재 된 값을 사용할 수 있는지 확인하고 같은 경우인지를 리턴하는 데 사용된다.

    retronym의 프리젠 테이션에서 간단한 예 :

    scala> implicit val a = "test" // define an implicit value of type String
    a: java.lang.String = test
    scala> val b = implicitly[String] // search for an implicit value of type String and assign it to b
    b: String = test
    scala> val c = implicitly[Int] // search for an implicit value of type Int and assign it to c
    <console>:6: error: could not find implicit value for parameter e: Int
           val c = implicitly[Int]
                             ^
    
  3. ==============================

    3.A "물고기을 가르쳐"대답은 Scaladoc의 나이틀리에서 현재 사용할 수있는 알파벳 멤버 인덱스를 사용하는 것입니다. 패키지 / 클래스 창 상단의 문자 (와 알파벳이 아닌 이름에 대한 #은 () 모든 클래스에서) 해당 문자로 시작하는 멤버 이름의 인덱스에 대한 링크입니다. 당신이 I를 선택하는 경우, 예를 들어, 당신은이 링크에서 방문 할 수 PREDEF 하나 개의 발생과 암시 적 항목을 찾을 수 있습니다.

    A "물고기을 가르쳐"대답은 Scaladoc의 나이틀리에서 현재 사용할 수있는 알파벳 멤버 인덱스를 사용하는 것입니다. 패키지 / 클래스 창 상단의 문자 (와 알파벳이 아닌 이름에 대한 #은 () 모든 클래스에서) 해당 문자로 시작하는 멤버 이름의 인덱스에 대한 링크입니다. 당신이 I를 선택하는 경우, 예를 들어, 당신은이 링크에서 방문 할 수 PREDEF 하나 개의 발생과 암시 적 항목을 찾을 수 있습니다.

  4. from https://stackoverflow.com/questions/3855595/what-is-the-scala-identifier-implicitly by cc-by-sa and MIT license