복붙노트

[SCALA] 중괄호와 괄호 사이 스칼라의 공식 차이는 무엇, 그리고 때 사용해야인가?

SCALA

중괄호와 괄호 사이 스칼라의 공식 차이는 무엇, 그리고 때 사용해야인가?

(괄호)와 중괄호의 함수에 전달 인자 사이의 공식적인 차이점은 무엇입니까 {}?

내가 스칼라 책의 프로그램에서받은 느낌은 그 스칼라의 매우 유연하고 내가 가장 좋아하는 하나를 사용해야합니다,하지만 난 다른 사람이하지 않는 반면 어떤 경우 컴파일 것을 찾을 수 있습니다.

예를 들어 (단지 예로서 의미, 나는 일반적인 경우,뿐만 아니라이 특정 예에 대해 설명 어떤 응답을 부탁드립니다)

val tupleList = List[(String, String)]()
val filtered = tupleList.takeWhile( case (s1, s2) => s1 == s2 )

=> 오류 : 단순한 표현의 불법 시작

val filtered = tupleList.takeWhile{ case (s1, s2) => s1 == s2 }

=> 미세.

해결법

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

    1.나는 이것에 대해 쓸 한 번했지만, 규칙이 어느 정도 확산이기 때문에 나는 결국 포기했다. 기본적으로, 당신은 그것의 묘리를 터득해야합니다.

    나는 이것에 대해 쓸 한 번했지만, 규칙이 어느 정도 확산이기 때문에 나는 결국 포기했다. 기본적으로, 당신은 그것의 묘리를 터득해야합니다.

    메서드 호출에 매개 변수를 전달할 때 : 아마도 그것은 중괄호와 괄호는 상호 교환 사용할 수있는 위치에 집중하는 것이 가장 좋습니다. 당신은 중괄호 경우에 괄호를 대체 할 수 있으며, 경우에만, 방법은 하나의 매개 변수를 기대하고있다. 예를 들면 :

    List(1, 2, 3).reduceLeft{_ + _} // valid, single Function2[Int,Int] parameter
    
    List{1, 2, 3}.reduceLeft(_ + _) // invalid, A* vararg parameter
    

    그러나의 더 당신은 더 나은 이러한 규칙을 이해하기 위해 알아야 할 필요가있다.

    그들은 검사 컴파일을 증가 제공하기 때문에 스프레이의 저자는 괄호 라운드 좋습니다. 이 스프레이와 같은 DSL에 특히 중요합니다. 괄호를 사용하여 당신은 단지 하나의 라인을 제공해야 컴파일러를 말하고있다; 당신이 실수로 두 개 이상의 줄 그러므로 경우, 그것은 불평 할 것이다. 이제이 중괄호의 경우되지 않습니다 - 예를 들어, 다음 코드를 컴파일, 어딘가 연산자를 잊지, 당신은 예기치 않은 결과를 얻을 가능성이 매우 어려운 버그를 찾을 경우. 아래는 (표현이 순수 적어도 경고를하기 때문에) 인위적인하지만 포인트를한다 :

    method {
      1 +
      2
      3
    }
    
    method(
      1 +
      2
      3
    )
    

    첫 번째 컴파일은, 두 번째는 오류가 있습니다 : ')'예상하지만, 정수 리터럴은 발견했다. 저자는 1 + 2 + 3을 쓰고 싶었다.

    하나는 기본 인자 다중 매개 변수 방법에 대한 비슷한 주장 할 수 있습니다; 그것은 괄호를 사용할 때 실수로 별도의 매개 변수에 쉼표를 잊지 불가능합니다.

    상세에 대한 중요한 종종 간과 참고. 불가피하게 중괄호를 사용하면 스칼라 스타일 가이드는 명확하게 중괄호를 닫는 것은 자신의 라인에 있어야한다고부터 코드를 자세히 사용자에 이르게 :

    대부분의 자동 reformatters는 인 IntelliJ처럼, 자동으로이 포맷을 다시 수행합니다. 그래서 때 당신이 할 수있는 둥근 괄호를 사용하여에 충실하려고합니다.

    중위 표기법, 목록 등 (1,2,3) 같이 IndexOf (2)를 사용할 때 당신은 단지 하나의 매개 변수가있는 경우 괄호를 생략하고리스트로 쓸 수 (1, 2, 3) 같이 IndexOf 2.이 도트의 경우가 아니다 -표기법.

    참고 또한 당신이 멀티 토큰을 표현하는 하나의 매개 변수가있을 때 같은 X + 2 또는 =>를 % 2 == 0, 당신은 표현의 경계를 표시하기 위해 괄호를 사용합니다.

    가끔 괄호를 생략 할 수 있기 때문에, 때로는 튜플처럼 별도의 괄호를 필요로 ((1, 2)), 때로는 외부 괄호에서와 같이 생략 될 수있다 (1, 2). 이 혼란의 원인이 될 수 있습니다.

    스칼라 함수 및 부분 함수 리터럴 구문을 갖는다. 그것은 다음과 같습니다 :

    {
        case pattern if guard => statements
        case pattern => statements
    }
    

    당신이 경우 문을 사용할 수있는 유일한 장소 원정 캐치 키워드 있습니다 :

    object match {
        case pattern if guard => statements
        case pattern => statements
    }
    
    try {
        block
    } catch {
        case pattern if guard => statements
        case pattern => statements
    } finally {
        block
    }
    

    당신은 다른 맥락에서 case 문을 사용할 수 없습니다. 당신이 케이스를 사용하고자한다면, 당신은 중괄호가 필요합니다. 경우 당신은 기능과 문자 부분 기능 사이의 차이를 만드는 것 궁금, 대답은 : 컨텍스트. 스칼라 함수를 기대하는 경우, 함수는 당신이 얻을. 이 부분 기능을 기대하는 경우 일부 기능을 얻을. 모두가 예상되는 경우, 모호함에 대한 오류를 제공합니다.

    괄호는 표현식을 사용할 수 있습니다. 중괄호 (이 함수 리터럴하지, 그래서 하나처럼 사용하려고 조심) 코드 블록을 사용할 수 있습니다. 코드 블록은 import 문, 선언 또는 식을 수 있습니다 각각의 여러 문으로 구성되어 있습니다. 그것은 다음과 같이 간다 :

    {
        import stuff._
        statement ; // ; optional at the end of the line
        statement ; statement // not optional here
        var x = 0 // declaration
        while (x < 10) { x += 1 } // stuff
        (x % 5) + 1 // expression
    }
    
    ( expression )
    

    당신은 선언, 여러 문장, 같은 가져 오기 또는 아무것도를 필요로한다면, 당신은 중괄호가 필요합니다. 표현식이 문이기 때문에, 괄호는 괄호 안에 표시 될 수 있습니다. 그러나 흥미로운 점은 코드 블록도 표현, 그래서 당신이 표현의 아무 곳이나 사용할 수 있다는 것입니다 :

    ( { var x = 0; while (x < 10) { x += 1}; x } % 5) + 1
    

    표현 문 및 코드의 블록이기 때문에 그래서, 표현, 아래 모든 것이 유효하다 :

    1       // literal
    (1)     // expression
    {1}     // block of code
    ({1})   // expression with a block of code
    {(1)}   // block of code with an expression
    ({(1)}) // you get the drift...
    

    기본적으로, 당신은 그 반대의 경우도 마찬가지 다른 곳으로 {} 대체 () 또는 수 없습니다. 예를 들면 :

    while (x < 10) { x += 1 }
    

    이 메소드 호출되지 않습니다, 그래서 당신은 다른 방법을 쓸 수 없습니다. 글쎄, 당신은 코드 블록에 대한 중괄호를 사용 괄호뿐만 아니라, 조건의 괄호 안에 중괄호를 넣을 수 있습니다 :

    while ({x < 10}) { (x += 1) }
    

    그래서, 난이 도움이되기를 바랍니다.

  2. ==============================

    2.여기에 무슨 다른 규칙과 추론의 몇 가지가 있습니다 : 모두의 첫 번째 매개 변수가 함수 인 경우, 스칼라는, 예를 괄호을 유추 중괄호가 추론 list.map (2 _ *)에서, 그것은 list.map 단지 짧은 형태의 ({_ * 2}). 두 번째로 그 매개 변수 목록은 하나 개의 매개 변수가있는 경우, 스칼라, 당신은 마지막 매개 변수 목록에 괄호를 생략 할 수 있으며 list.foldLeft (0) (_ + _) list.foldLeft과 같이 쓸 수있다 그래서, 함수 (0) {_ + _} (또는 list.foldLeft (0) ({_ + _}) 당신이 명시 적으로 추가되고 싶은 경우).

    여기에 무슨 다른 규칙과 추론의 몇 가지가 있습니다 : 모두의 첫 번째 매개 변수가 함수 인 경우, 스칼라는, 예를 괄호을 유추 중괄호가 추론 list.map (2 _ *)에서, 그것은 list.map 단지 짧은 형태의 ({_ * 2}). 두 번째로 그 매개 변수 목록은 하나 개의 매개 변수가있는 경우, 스칼라, 당신은 마지막 매개 변수 목록에 괄호를 생략 할 수 있으며 list.foldLeft (0) (_ + _) list.foldLeft과 같이 쓸 수있다 그래서, 함수 (0) {_ + _} (또는 list.foldLeft (0) ({_ + _}) 당신이 명시 적으로 추가되고 싶은 경우).

    당신은 다른 사람이 대신 함수의 일부 기능을 언급 한대로, 얻을 경우를 추가하고 스칼라, 일부 기능에 괄호를 추측하지 않을 경우, list.map 있도록 (경우 X => X * 2) 작동하지 않습니다 하지만, 두 list.map ({경우 X => 2 * 2}) 및 {list.map 경우 X => X * 2} 것이다.

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

    3.http://www.codecommit.com/scala-style-guide.pdf : 중괄호 괄호의 사용을 표준화 할 수있는 사회의 노력이있다, 스칼라 스타일 가이드 (21 페이지)를 참조하십시오

    http://www.codecommit.com/scala-style-guide.pdf : 중괄호 괄호의 사용을 표준화 할 수있는 사회의 노력이있다, 스칼라 스타일 가이드 (21 페이지)를 참조하십시오

    고차 방법에 권장되는 구문은 항상 중괄호를 사용하고, 점을 생략하는 것입니다 호출

    val filtered = tupleList takeWhile { case (s1, s2) => s1 == s2 }
    

    "정상"metod 당신은 점과 괄호를 사용한다 호출합니다.

    val result = myInstance.foo(5, "Hello")
    
  4. ==============================

    4.나는 스칼라에 중괄호에 대한 특정 아무것도 복잡한이라고 생각하지 않습니다. 스칼라에서 그들의 보이는 복잡한 사용법을 마스터하기 위해, 단지 마음에 간단한 몇 가지를 유지 :

    나는 스칼라에 중괄호에 대한 특정 아무것도 복잡한이라고 생각하지 않습니다. 스칼라에서 그들의 보이는 복잡한 사용법을 마스터하기 위해, 단지 마음에 간단한 몇 가지를 유지 :

    의는 위의 세 가지 규칙에 따라 몇 가지 예를 설명하자 :

    val tupleList = List[(String, String)]()
    // doesn't compile, violates case clause requirement
    val filtered = tupleList.takeWhile( case (s1, s2) => s1 == s2 ) 
    // block of code as a partial function and parentheses omission,
    // i.e. tupleList.takeWhile({ case (s1, s2) => s1 == s2 })
    val filtered = tupleList.takeWhile{ case (s1, s2) => s1 == s2 }
    
    // curly braces omission, i.e. List(1, 2, 3).reduceLeft({_+_})
    List(1, 2, 3).reduceLeft(_+_)
    // parentheses omission, i.e. List(1, 2, 3).reduceLeft({_+_})
    List(1, 2, 3).reduceLeft{_+_}
    // not both though it compiles, because meaning totally changes due to precedence
    List(1, 2, 3).reduceLeft _+_ // res1: String => String = <function1>
    
    // curly braces omission, i.e. List(1, 2, 3).foldLeft(0)({_ + _})
    List(1, 2, 3).foldLeft(0)(_ + _)
    // parentheses omission, i.e. List(1, 2, 3).foldLeft(0)({_ + _})
    List(1, 2, 3).foldLeft(0){_ + _}
    // block of code and parentheses omission
    List(1, 2, 3).foldLeft {0} {_ + _}
    // not both though it compiles, because meaning totally changes due to precedence
    List(1, 2, 3).foldLeft(0) _ + _
    // error: ';' expected but integer literal found.
    List(1, 2, 3).foldLeft 0 (_ + _)
    
    def foo(f: Int => Unit) = { println("Entering foo"); f(4) }
    // block of code that just evaluates to a value of a function, and parentheses omission
    // i.e. foo({ println("Hey"); x => println(x) })
    foo { println("Hey"); x => println(x) }
    
    // parentheses omission, i.e. f({x})
    def f(x: Int): Int = f {x}
    // error: missing arguments for method f
    def f(x: Int): Int = f x
    
  5. ==============================

    5.나는 그것이 함수 호출 이유는 여러 가지 일이 자신의 사용을 설명하는 가치라고 생각합니다. 누군가가 이미 말했듯이 중괄호는 표현이 예상되며,이 평가 될 위치를 너무 넣을 수있는 표현입니다 코드 블록을 정의합니다. 평가 때, 그 문은 실행과의 마지막 문장의 값은 (다소 루비처럼) 전체 블록 평가의 결과이다.

    나는 그것이 함수 호출 이유는 여러 가지 일이 자신의 사용을 설명하는 가치라고 생각합니다. 누군가가 이미 말했듯이 중괄호는 표현이 예상되며,이 평가 될 위치를 너무 넣을 수있는 표현입니다 코드 블록을 정의합니다. 평가 때, 그 문은 실행과의 마지막 문장의 값은 (다소 루비처럼) 전체 블록 평가의 결과이다.

    우리는 같은 일을 할 수 있다는 데 :

    2 + { 3 }             // res: Int = 5
    val x = { 4 }         // res: x: Int = 4
    List({1},{2},{3})     // res: List[Int] = List(1,2,3)
    

    마지막 예는 각각이 먼저 평가되는 세 개의 파라미터와 단지 함수 호출이다.

    이 함수 호출과 어떻게 작동하는지 이제 매개 변수로 다른 기능을 가지고 간단한 함수를 정의 할 수 있습니다 볼 수 있습니다.

    def foo(f: Int => Unit) = { println("Entering foo"); f(4) }
    

    를 호출하기 위해, 우리는 int 형 중 하나 PARAM 소요 기능을 전달해야합니다, 그래서 우리는 문자 그대로의 기능을 사용하고 foo는 그것을 전달할 수 있습니다 :

    foo( x => println(x) )
    

    이제 우리는 표현 대신에 코드의 블록을 사용하기 전에 그래서 그것을 사용하게 말했다

    foo({ x => println(x) })
    

    여기에서 일어나는 일은이 값은 다음으로 foo에 전달되고, {}는 평가 안에 그 코드이며, 함수 값은 블록 평가 값으로 반환됩니다. 이 의미 이전 호출과 동일합니다.

    그러나 우리는 더 많은 것을 추가 할 수 있습니다 :

    foo({ println("Hey"); x => println(x) })
    

    이제 우리의 코드 블록은 두 문장을 포함하고,이 foo를 실행하기 전에 평가되기 때문에, 무슨 일 "야"가 인쇄 된 첫 번째, 그 다음 우리의 기능은 "foo는 입력", foo는에 전달 인쇄 그리고 마지막으로 "4"가 인쇄되어 있다는 것입니다 .

    하지만 이것은 조금 추한 외모와 스칼라는이 경우 괄호를 건너 우리를 할 수 있습니다, 그래서 우리가 쓸 수 있습니다 :

    foo { println("Hey"); x => println(x) }
    

    또는

    foo { x => println(x) }
    

    그게 훨씬 낫 네요과 전 것과 동일합니다. 여기서 여전히 코드 블록은 제 평가 인자로서 푸 (X =>에 println (x)의 경우) 통과 평가의 결과이다.

  6. ==============================

    6.당신이 케이스를 사용하고 있기 때문에,이 부분 함수를 정의하고, 일부 기능은 중괄호가 필요합니다.

    당신이 케이스를 사용하고 있기 때문에,이 부분 함수를 정의하고, 일부 기능은 중괄호가 필요합니다.

  7. ==============================

    7.괄호로 확인 증가 컴파일

    괄호로 확인 증가 컴파일

    스프레이의 저자는, 둥근 괄호 검사 컴파일을 증가주는 것이 좋습니다. 이 스프레이와 같은 DSL에 특히 중요합니다. 괄호를 사용하여 당신은 당신이 실수로 두 개 이상의, 그것은 불평했다 그러므로 경우, 그것은 단지 하나의 라인을 제공해야 컴파일러를 말하고있다. 예를 들어, 당신이 어딘가에 코드가 예기치 않은 결과 찾을 가능성이 매우 어려운 버그를 얻을, 컴파일 연산자를 잊어 버린 경우 지금이 중괄호의 경우되지 않습니다. 아래는 (표현이 순수 적어도 경고를하기 때문에) 인위적인하지만 포인트를한다

    method {
      1 +
      2
      3
    }
    
    method(
      1 +
      2
      3
     )
    

    첫 번째 컴파일은, 두 번째는 오류가 있습니다 : ')'예상하지만, 정수 리터럴은 발견했다. 저자는 1 + 2 + 3을 쓰고 싶었다.

    하나는 기본 인자 다중 매개 변수 방법에 대한 비슷한 주장 할 수 있습니다; 그것은 괄호를 사용할 때 실수로 별도의 매개 변수에 쉼표를 잊지 불가능합니다.

    다변

    상세에 대한 중요한 종종 간과 참고. http://docs.scala-lang.org/style/declarations.html "... 닫는 중괄호 : 불가피하게 중괄호를 사용하면 스칼라 스타일 가이드는 명확하게 중괄호를 닫는 것은 자신의 라인에 있어야한다고부터 코드를 자세히 사용자에 이르게 바로 함수의 마지막 줄에 다음 한 줄에 있습니다. " 대부분의 자동 reformatters는 인 IntelliJ처럼, 자동으로이 포맷을 다시 수행합니다. 그래서 때 당신이 할 수있는 둥근 괄호를 사용하여에 충실하려고합니다. 예를 들면 목록 (1, 2, 3) .reduceLeft {_ + _}이된다 :

    List(1, 2, 3).reduceLeft {
      _ + _
    }
    
  8. ==============================

    8.중괄호로, 당신은 세미콜론 당신을 위해 유도하지 괄호를 받았습니다. 그것은 부분적인 기능을 기대하기 때문에, takeWhile 기능을 고려해야 만 {경우 XXX => ??? } 대신 CASE 표현식 괄호의 올바른 정의입니다.

    중괄호로, 당신은 세미콜론 당신을 위해 유도하지 괄호를 받았습니다. 그것은 부분적인 기능을 기대하기 때문에, takeWhile 기능을 고려해야 만 {경우 XXX => ??? } 대신 CASE 표현식 괄호의 올바른 정의입니다.

  9. from https://stackoverflow.com/questions/4386127/what-is-the-formal-difference-in-scala-between-braces-and-parentheses-and-when by cc-by-sa and MIT license