복붙노트

[SCALA] 스칼라 형 ascriptions의 목적은 무엇인가?

SCALA

스칼라 형 ascriptions의 목적은 무엇인가?

형의 귀속이 무엇인지에 스펙에 많은 정보가 아니라, 확실히 그것을위한 목적에 대한 거기에 아무것도 없다. 나는 형의 귀속은 무엇을 사용하는 것 "변수 인수 작업을 전달하고"이외의? 아래 구문과 사용의 효과에 대한 몇 가지 스칼라 REPL이다.

scala> val s = "Dave"
s: java.lang.String = Dave

scala> val p = s:Object
p: java.lang.Object = Dave

scala> p.length
<console>:7: error: value length is not a member of java.lang.Object
       p.length
         ^
scala> p.getClass
res10: java.lang.Class[_ <: java.lang.Object] = class java.lang.String

scala> s.getClass
res11: java.lang.Class[_ <: java.lang.Object] = class java.lang.String

scala> p.asInstanceOf[String].length
res9: Int = 4

해결법

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

    1.유형의 귀속은 가능한 모든 유효한 유형의 당신이 표현에서 기대하는 어떤 종류의 컴파일러를 말하고있다.

    유형의 귀속은 가능한 모든 유효한 유형의 당신이 표현에서 기대하는 어떤 종류의 컴파일러를 말하고있다.

    이 같은 분산 및 유형 선언 등 기존의 제약을 존중 경우 유형은 유효합니다, 그것은 어느 유형 중 하나는 표현이에, 또는 범위에 적용되는 변환있다 "는는"적용이다.

    그래서, java.lang.String의는 java.lang.Object 상위 그러므로 어떤 문자열도 객체이며, 확장합니다. 귀하의 예제에서 당신은 당신이 표현의 객체가 아닌 문자열로 취급하려는 선언했다. 거기를 방해하는 제약 조건입니다 원하는 유형이 유형의 중 하나가입니다 때문에, 그것은 작동합니다.

    이제, 당신은 왜 그할까요? 이걸 고려하세요:

    scala> val s = "Dave"
    s: java.lang.String = Dave
    
    scala> val p = s: Object
    p: java.lang.Object = Dave
    
    scala> val ss = scala.collection.mutable.Set(s)
    ss: scala.collection.mutable.Set[java.lang.String] = Set(Dave)
    
    scala> val ps = scala.collection.mutable.Set(p)
    ps: scala.collection.mutable.Set[java.lang.Object] = Set(Dave)
    
    scala> ss += Nil
    <console>:7: error: type mismatch;
     found   : scala.collection.immutable.Nil.type (with underlying type object Nil)
     required: java.lang.String
           ss += Nil
                 ^
    
    scala> ps += Nil
    res3: ps.type = Set(List(), Dave)
    

    또한 SS 선언에 형 ascripting s에 의해이 문제를 해결 한 수, 또는 당신은 [AnyRef] 설정 될 SS의 유형을 선언 할 수있다.

    당신이 식별자에 값을 할당하는 그러나, 타입 선언은 오랫동안 같은 일을 달성한다. 이렇게 항상 할 수있는 한, 물론, 하나는 원샷 식별자와 코드를 넘쳐 걱정하지 않는 경우. 예를 들어, 다음은 컴파일되지 않습니다 :

    def prefixesOf(s: String) = s.foldLeft(Nil) { 
      case (head :: tail, char) => (head + char) :: head :: tail
      case (lst, char) => char.toString :: lst
    }
    

    그러나이 작업을 수행합니다

    def prefixesOf(s: String) = s.foldLeft(Nil: List[String]) { 
      case (head :: tail, char) => (head + char) :: head :: tail
      case (lst, char) => char.toString :: lst
    }
    

    무기 호 대신에 여기 식별자를 사용하는 것이 어리석은 것입니다. 난 그냥 목록 [문자열]을 쓸 수 있지만 그리고 () 대신에, 그것은 항상 옵션을 선택하지 않습니다. 예를 들어, 이것을 고려 :

    def firstVowel(s: String) = s.foldLeft(None: Option[Char]) { 
      case (None, char) => if ("aeiou" contains char.toLower) Some(char) else None
      case (vowel, _) => vowel
    }
    

    참고로,이 스칼라 2.7 사양 (2009년 3월 15일 초안) 형의 귀속에 관하여 말해야하는 것입니다 :

    Expr1 ::= ...
            | PostfixExpr Ascription
    
    Ascription ::= ‘:’ InfixType
                 | ‘:’ Annotation {Annotation}
                 | ‘:’ ‘_’ ‘*’
    
  2. ==============================

    2.하나의 가능성이있는 경우 네트워크 및 직렬 프로토콜 수준의 물건, 다음이 :

    하나의 가능성이있는 경우 네트워크 및 직렬 프로토콜 수준의 물건, 다음이 :

    val x = 2 : Byte
    

    보다 훨씬 깨끗

    val x = 2.asInstanceOf[Byte]
    

    두 번째 형태는 또한 런타임 변환 (컴파일러에 의해 처리되지 않음) 몇 가지 흥미로운 이상 / 언더 플로우 조건으로 이어질 수있다.

  3. ==============================

    3.나는 스칼라의 타입 추론에 구멍을 통해 용지 종류의 귀속을 사용합니다. 예를 들어, A 형의 콜렉션 foldLeft 초기 요소로 컬렉션의 요소를 접어서 사용되는 타입 B 및 기능 (B, A) => B의 초기 요소를 가져. 타입 B의 실제 값은 초기 요소의 형태로부터 추론된다. 닐 목록 [없음]을 연장하기 때문에, 초기의 소자로 사용은 문제를 일으킨다 :

    나는 스칼라의 타입 추론에 구멍을 통해 용지 종류의 귀속을 사용합니다. 예를 들어, A 형의 콜렉션 foldLeft 초기 요소로 컬렉션의 요소를 접어서 사용되는 타입 B 및 기능 (B, A) => B의 초기 요소를 가져. 타입 B의 실제 값은 초기 요소의 형태로부터 추론된다. 닐 목록 [없음]을 연장하기 때문에, 초기의 소자로 사용은 문제를 일으킨다 :

    scala> val x = List(1,2,3,4)
    x: List[Int] = List(1, 2, 3, 4)
    
    scala> x.foldLeft(Nil)( (acc,elem) => elem::acc)
    <console>:9: error: type mismatch;
     found   : List[Int]
     required: scala.collection.immutable.Nil.type
                  x.foldLeft(Nil)( (acc,elem) => elem::acc)
                                                     ^
    
    scala> x.foldLeft(Nil:List[Int])( (acc,elem) => elem::acc )
    res2: List[Int] = List(4, 3, 2, 1)
    

    목록 [지능] : 또는, 당신은 단지 List.empty [지능] 대신 무기 호를 사용할 수 있습니다.

    scala> x.foldLeft(List.empty[Int])( (acc,elem) => elem::acc )
    res3: List[Int] = List(4, 3, 2, 1)
    

    편집 : List.empty [A]로서 구현

    override def empty[A]: List[A] = Nil
    

    (출처)

    이것은 효과적으로 무기 호에 대한보다 자세한 형태 : 목록 [A]

  4. ==============================

    4.당신은 조금 따라 뒤얽힌 경우이 스레드, 조명 찾을 수 있습니다. 중요한 점은 제약 조건을 추가하는 것은 유형 검사에 힌트이다 - 그것은 당신에게 그 컴파일 단계가 무엇을하고 있는지를 통해 좀 더 제어 할 수 있습니다.

    당신은 조금 따라 뒤얽힌 경우이 스레드, 조명 찾을 수 있습니다. 중요한 점은 제약 조건을 추가하는 것은 유형 검사에 힌트이다 - 그것은 당신에게 그 컴파일 단계가 무엇을하고 있는지를 통해 좀 더 제어 할 수 있습니다.

  5. ==============================

    5.추론을 입력합니다. 우리는 유형 추론라는 소스 코드에 뭔가 유형의 이름을 부여 명시 적으로 건너 뛸 수 있습니다 (일부 예외적 인 경우에 필요한 있습니다.)

    추론을 입력합니다. 우리는 유형 추론라는 소스 코드에 뭔가 유형의 이름을 부여 명시 적으로 건너 뛸 수 있습니다 (일부 예외적 인 경우에 필요한 있습니다.)

    유형의 귀속 : 뭔가의 유형이 유형 귀속 호출에 대해 명시된다. 그것은 어떤 차이를 만들 수 있습니까?

    예 : 발 X = 2 : 바이트

    또한 참조 : 1. 우리는 명시 적으로 우리의 함수 반환 유형을 제공 할 수 있습니다

    def t1 : Option[Option[String]] = Some(None)
    
    > t1: Option[Option[String]]
    

    수이 선언의 또 다른 방법 :

    def t2 = Some(None: Option[String])
    > t2: Some[Option[String]]
    

    여기에서 우리는 명시 적으로 옵션 [옵션 [문자열]] 반환 유형을 포기하지 않았고 컴파일러 일부 [옵션 [문자열]]로 추정. 일부 [옵션 [문자열]] 왜 우리는 정의 유형의 귀속을 사용하기 때문이다.

    이 시간 우리는 명시 적으로 컴파일러 아무것도 (도이 데피)를 말하지 않았다. 그리고 그것은 일부 [None.type] 우리의 정의를 유추

  6. from https://stackoverflow.com/questions/2087250/what-is-the-purpose-of-type-ascriptions-in-scala by cc-by-sa and MIT license