3

대괄호 및/또는 마침표를 생략 할 수 있는지 여부를 이해하는 데 가장 힘든 시간을 보내고 있습니다. 이것은 _과 상호 작용합니다.명명 된 매개 변수 vs _, 점 표기법 v 중위 연산자 v 스칼라에서 고차 함수를 사용할 때 중괄호 대괄호 대괄호

내가이 함께했다 특정 경우

val x: X = ??? 
val xss: List[List[X]] = ??? 
xss map x :: _ //this doesn't compile 
xss map _.::(x) //this is the same as the above (and thus doesn't compile) 

위의 두 가지가 한편 xss.map(_).::(x)

xss map (x :: _) //this works as expected 
xss map {x :: _} //this does the same thing as the above 

동일 것 같다이었다, 다음도 실패 :

xss.map xs => x :: xs //';' expected but '=>' found. 
xss.map x :: _ //missing arguments for method map in class List; follow this method with `_' if you want to treat it as a partially applied function 
//so when I try following the method with _, I get my favourite: 
xss.map _ x :: _ //Cannot construct a collection of type That with elements of type B based on a collection of type List[List[Main.X]] 
//as opposed to 
xss map _ x :: _ //missing parameter type for expanded function ((x$1) => xss.map(x$1).x(($colon$colon: (() => <empty>)))) 

오른쪽 지금, 나는 종종 "컴파일 될 때까지 심볼을 토글 (toggle)"하고 플레이한다. 차선책의 프로그래밍 전략. 이 모든게 어떻게 작동합니까?

+2

http://stackoverflow.com/questions/2173373/scala-foreach-strange-behaviour를 보았습니까? – sschaef

+0

아직 감사합니다. 찾고. – Martijn

+1

이것은 괄호/점을 생략 할 수있는 문제에 도움이됩니다. http://stackoverflow.com/questions/1181533/what-are-the-precise-rules-for-when-you-can-omit-parenthesis- 도트 중괄호 -f – sschaef

답변

2

먼저 xss.map(f)xss map f을 구별해야합니다. Scala Documentation에 따르면 단일 매개 변수를 사용하는 모든 메서드를 삽입 연산자로 사용할 수 있습니다.

실제로 map method in List은 이러한 방법 중 하나입니다. 다음과 같이 전체 서명이 TraversableLike로부터 상속 있다는 사실을 무시하고, 서명은 다음과 같습니다

final def map[B](f: (A) ⇒ B): List[B] 

그래서이 유형 A => B와 함수 인 단일 매개 변수, 즉 f을합니다. 당신은 이것은 취향의 문제가 있지만

xss.map(mySize) 

또는

xss map mySize 

사이가 function value 정의
val mySize = (xs:List[Int]) => xs.size 

당신이 선택할 수있는 경우에 따라서 Scala Style Guide에 따라,이 경우를 들어, 후자는 점 표기법을 사용하는 것이 더 복잡한 복잡한 표현의 일부가 아닌 한 선호됩니다.

도트 표기법을 사용하려면 항상 함수 응용 프로그램을 대괄호로 한정해야합니다. 그래서 다음 중 어느 것도 성공적으로 컴파일되지 않습니다.

xss.map xs => x :: xs // Won't compile 
xss.map x :: _ // Won't compile 
xss.map _ x :: _ // Won't compile 

그러나 당신이 function literal (일명 anonymous function)을 통과하는 데 필요한 대부분의 시간 대신에 함수 값을 전달하는. 이 경우 점 표기법을 사용하면 다시 xss.map(_.size)과 같은 것이 필요합니다. 그러나 삽입 기호 표기법을 사용하면 우선 순위가 결정됩니다.

xss map x :: _ // Won't compile! 

예를

를 들어

때문에 연산자 우선 순위 작동하지 않습니다. 컴파일러의 상황을 명확하게하기 위해 대괄호를 사용해야합니다. xss map (x :: _).

대괄호 대신 중괄호를 사용하면 매우 명확하고 간단한 규칙이 적용됩니다. 다시 한 번 매개 변수를 취하는 모든 함수는 중선 및 점 표기법 모두 대괄호 대신 중괄호로 적용 할 수 있습니다.따라서 다음 문장이 컴파일됩니다.

xss.map{x :: _} 
xss map {x :: _} 

혼란을 피하기 위해 점 표기법과 매개 변수의 명시 적 유형으로 시작할 수 있습니다. 나중에 컴파일 된 후 코드에 대한 단위 테스트를 작성하는 등 불필요한 형식을 제거하고 중위 표기법을 사용하고 중괄호 대신 중괄호를 사용하여 코드를 리팩토링 할 수 있습니다.

스칼라 코딩 스타일과 관련된 Scala Style GuideMartin Odersky's talk in Scala Days 2013을 참조 할 수 있습니다. 또한 코드를보다 간결하게 리팩터링하는 데있어 IDE의 도움을 요청할 수 있습니다.

+0

좋은 답변, 감사합니다. 필자의 경험으로 보면, 필자는 Eclipse 플러그인을 사용하여 내 코드를 리팩토링 할 것을 요청했다. intellij에 대한 좋은 일을 시작하기는하지만 – Martijn

+0

[IntelliJ IDEA Scala Plugin] (http://plugins.jetbrains.com/)과 함께 즐거운 시간을 보낸다. 플러그인 /? id = 1347). 더 간단해질 수있는 코드 부분을 자동으로 감지합니다. 예를 들어,'xss map (mySize)'를 쓰면 둥근 괄호를 지우라고 제안 할 것이다. 'xss map (mySize (_)) '라고 써도 불필요한'_'을 먼저 제거한 다음 제거한 후 대괄호를 제거하라는 의미입니다. 일반적인 문제 및 코드 냄새의 대부분을 감지 할만큼 똑똑합니다. –