수색…


비고

값과 변수 이름은 더 낮은 낙타의 경우 여야합니다.

상수 이름은 위 낙타 경우이어야합니다. 즉, 멤버가 final이며 불변이며 패키지 객체 또는 객체에 속한 경우, 상수로 간주 될 수 있습니다

방법, 값 및 변수 이름은 더 낮은 낙타의 경우 여야합니다.

출처 : http://docs.scala-lang.org/style/naming-conventions.html

이 컴파일 :

val (a,b) = (1,2)
// a: Int = 1
// b: Int = 2

하지만 그렇지 않습니다.

val (A,B) = (1,2)
// error: not found: value A
// error: not found: value B

val과 var가 아닌

valvar

scala> val a = 123
a: Int = 123

scala> a = 456
<console>:8: error: reassignment to val
       a = 456

scala> var b = 123
b: Int = 123

scala> b = 321
b: Int = 321
  • val 참조는 변경할 수 없습니다. Javafinal 변수와 같이 일단 초기화되면 변경할 수 없습니다.
  • var 참조는 Java에서 간단한 변수 선언으로 재 할당 가능

변경할 수없는 컬렉션과 변경 가능 컬렉션

  val mut = scala.collection.mutable.Map.empty[String, Int]
  mut += ("123" -> 123)
  mut += ("456" -> 456)
  mut += ("789" -> 789)

  val imm = scala.collection.immutable.Map.empty[String, Int]
  imm + ("123" -> 123)
  imm + ("456" -> 456)
  imm + ("789" -> 789)

  scala> mut
    Map(123 -> 123, 456 -> 456, 789 -> 789)

  scala> imm
    Map()

scala> imm + ("123" -> 123) + ("456" -> 456) + ("789" -> 789)
    Map(123 -> 123, 456 -> 456, 789 -> 789)

스칼라 표준 라이브러리는 불변의 데이터 구조와 변경 가능한 데이터 구조를 제공한다. 변경할 수없는 데이터 구조가 "수정"될 때마다 원본 컬렉션을 현재 위치에서 수정하는 대신 새 인스턴스가 생성됩니다. 컬렉션의 각 인스턴스는 다른 인스턴스와 중요한 구조를 공유 할 수 있습니다.

변경 가능하고 변경 불가능한 콜렉션 (공식 스칼라 문서)

하지만이 경우에는 불변성을 사용할 수 없습니다!

2 Map 을 취하고 mamb 모든 요소를 ​​포함하는 Map 을 반환하는 함수를 예제로 선택해 보겠습니다.

def merge2Maps(ma: Map[String, Int], mb: Map[String, Int]): Map[String, Int]

첫 번째 시도는 for ((k, v) <- map) 사용하여지도 중 하나의 요소를 반복하고 병합 된지도를 반환 할 수 있습니다.

def merge2Maps(ma: ..., mb: ...): Map[String, Int] = {

  for ((k, v) <- mb) {
    ???
  }

}

이 첫 번째 움직임은 즉시 구속을 추가 돌연변이를 그 외부 for 지금 필요합니다. 해제 절임 때 더 명확하다 for :

// this:
for ((k, v) <- map) { ??? }

// is equivalent to:
map.foreach { case (k, v) => ??? }

"왜 우리가 돌연변이를해야합니까?"

foreach 는 부작용에 의존합니다. 우리가 foreach 내에서 어떤 일이 일어나길 원할 때마다 우리는 "부작용"이 필요합니다.이 경우 변수 var result 변경하거나 변경 가능한 데이터 구조를 사용할 수 있습니다.

result 맵 작성 및 채우기

의는 가정하자 mamb 있습니다 scala.collection.immutable.Map , 우리가 만들 수 있습니다 result 에서지도 ma :

val result = mutable.Map() ++ ma

그런 다음 요소를 추가하는 mb 반복하고 ma 에있는 현재 요소의 key 가 이미있는 경우 mb 대체합니다.

mb.foreach { case (k, v) => result += (k -> v) }

변경 가능한 구현

지금까지는 "변경 가능한 모음을 사용해야했습니다."라고 말하면 올바른 구현이 될 수 있습니다.

def merge2Maps(ma: Map[String, Int], mb: Map[String, Int]): Map[String, Int] = {
  val result = scala.collection.mutable.Map() ++ ma
  mb.foreach { case (k, v) => result += (k -> v) }
  result.toMap // to get back an immutable Map
}

예상대로 :

scala> merge2Maps(Map("a" -> 11, "b" -> 12), Map("b" -> 22, "c" -> 23))
  Map(a -> 11, b -> 22, c -> 23)

구조에 접히기

이 시나리오에서 foreach 를 제거하려면 어떻게해야합니까? 우리가해야할 일은 기본적으로 콜렉션 요소를 반복하고 옵션을 누적하는 동안 함수를 적용하는 것입니다. 옵션을 .foldLeft :

def merge2Maps(ma: Map[String, Int], mb: Map[String, Int]): Map[String, Int] = {
  mb.foldLeft(ma) { case (result, (k, v)) => result + (k -> v) }
  // or more concisely mb.foldLeft(ma) { _ + _ }
}

이 경우 우리의 "결과"는 .foldLeftzeroma 부터 시작하는 누적 값입니다.

중간 결과

분명히 이것은 불변의 솔루션은 생산 및 많은 파괴 Map 접는 동안 인스턴스를하지만, 그 인스턴스의 전체 클론 아니라는 것을 언급 할 가치가 Map 축적 대신 기존 인스턴스에 중요한 구조 (데이터를) 공유하고 있습니다.

더 쉬운 합리성

.foldLeft 접근법처럼 선언적이라면 의미에 대해 추론하는 것이 더 쉽습니다. 불변의 데이터 구조를 사용하면 우리의 구현을 쉽게 추론 할 수 있습니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow