diff --git a/_ko/tour/classes.md b/_ko/tour/classes.md index 4ed82e04c3..171079ebb3 100644 --- a/_ko/tour/classes.md +++ b/_ko/tour/classes.md @@ -8,41 +8,99 @@ language: ko next-page: traits previous-page: unified-types +topics: classes +prerequisite-knowledge: no-return-keyword, type-declaration-syntax, string-interpolation, procedures --- -스칼라의 클래스는 런타임에 많은 객체로 인스턴스화 될 수 있는 정적 템플릿이다. -아래는 'Point' 클래스의 정의이다. +스칼라의 클래스는 객체를 만들기 위한 설계도입니다. 클래스에는 _멤버_ 라고 통칭할 수 있는 메서드, 값, 변수, 타입, 객체, 트레잇, 클래스를 포함할 수 있습니다. 타입, 객체, 트레잇은 투어에서 나중에 다루겠습니다. - class Point(xc: Int, yc: Int) { - var x: Int = xc - var y: Int = yc - def move(dx: Int, dy: Int): Unit = { - x = x + dx - y = y + dy - } - override def toString(): String = "(" + x + ", " + y + ")"; - } +# 클래스 정의 +가장 단순한 클래스 정의는 예약어 `class`와 식별자만 있는 것입니다. 클래스명은 대문자로 시작하는 것이 관례입니다. +```tut +class User -이 클래스는 변수 'x' 와 'y' 그리고 두 메서드 `move` 와 `toString` 을 정의한다. `move`는 두 개의 정수를 인자로 받지만 값을 반환하지는 않는다 (암시적 반환 타입인 `Unit` 은 Java와 같은 언어의 `void` 에 해당한다). 반면 `toString`은 아무 파라미터도 입력받지 않지만 `String` 값을 반환한다. `toString`은 기정의된 `toString` 메서드를 오버라이드 하기 때문에 `override` 플래그로 표시되어야 한다. +val user1 = new User +``` +예약어 `new`는 클래스의 인스턴스를 만들기위해 사용합니다. `User` 클래스는 생성자를 정의하지 않았기 때문에 인자가 없는 기본 생성자를 갖습니다. 생성자와 클래스 몸체를 정의하고자 한다면, 다음의 클래스 정의 예제를 참고하십시오: -스칼라의 클래스들은 생성자의 인자로 파라미터화 된다. 위의 코드는 두 개의 생성자 인자 `xc`와 `yc`를 정의한다. 이 두 인자는 클래스 전체에서 접근 가능하다. 예제에서 이들은 변수 `x`와 `y`를 초기화하는 데에 사용된다. +```tut +class Point(var x: Int, var y: Int) { -클래스들은 아래의 예제가 보여주는 것처럼 새로운 기본형으로 초기화된다. + def move(dx: Int, dy: Int): Unit = { + x = x + dx + y = y + dy + } - object Classes { - def main(args: Array[String]): Unit = { - val pt = new Point(1, 2) - println(pt) - pt.move(10, 10) - println(pt) - } - } + override def toString: String = + s"($x, $y)" +} -이 프로그램은 `main` 메서드를 가지고 있는 최상위 싱글톤의 형태로 실행가능한 어플리케이션 클래스를 정의한다. `main` 메서드는 새로운 `Point`를 생성하고 변수 `pt`에 저장한다. `val` 키워드로 정의된 값은 변경을 허용하지 않는다는 점에서 `var` 키워드로 정의된 값(`Point` 클래스 참)과는 다르다는 점에 주의하자. 즉, 이 값은 상수이다. +val point1 = new Point(2, 3) +point1.x // 2 +println(point1) // prints (2, 3) +``` -이 프로그램의 결과는 아래와 같다: +이 `Point` 클래스에는 네 개의 멤버가 있습니다: 변수 `x`, `y`와 메서드 `move`, `toString`. 많은 다른 언어와 달리 기본 생성자는 클래스 서명부(signature)에 있습니다 `(var x : Int, var y : Int)`. `move` 메소드는 두 개의 정수 인자를 취하여 정보를 전달하지 않는 Unit 타입의 값 `()`을 반환합니다. 이것은 자바 같은 언어의 `void`와 유사합니다. 반면에 `toString`은 인자를 취하지 않고 `String` 값을 반환합니다. `toString`은 [`AnyRef`](unified-types.html)의 `toString`을 대체하므로 `override` 예약어로 지정됩니다. - (1, 2) - (11, 12) +## 생성자 -윤창석, 이한욱 옮김 +생성자는 다음과 같은 기본 값을 제공하여 선택적 매개변수를 가질 수 있습니다: + +```tut +class Point(var x: Int = 0, var y: Int = 0) + +val origin = new Point // x and y are both set to 0 +val point1 = new Point(1) +println(point1.x) // prints 1 + +``` + +이 버전의 `Point` 클래스에서 `x`와 `y` 인자는 기본 값 `0`을 가지므로 인자를 꼭 전달하지 않아도 됩니다. 생성자는 인자를 왼쪽부터 읽으므로 `y` 값만 전달하고 싶다면 매개변수의 이름을 지정해야 합니다. +``` +class Point(var x: Int = 0, var y: Int = 0) +val point2 = new Point(y=2) +println(point2.y) // prints 2 +``` + +이것은 명료성 향상을 위한 좋은 습관이기도 합니다. + +# Private 멤버와 Getter/Setter 문법 +멤버는 기본적으로 public으로 지정됩니다. `private` 접근 지시자를 사용함으로써 클래스 외부로부터 멤버를 숨길 수 있습니다. +```tut +class Point { + private var _x = 0 + private var _y = 0 + private val bound = 100 + + def x = _x + def x_= (newValue: Int): Unit = { + if (newValue < bound) _x = newValue else printWarning + } + + def y = _y + def y_= (newValue: Int): Unit = { + if (newValue < bound) _y = newValue else printWarning + } + + private def printWarning = println("WARNING: Out of bounds") +} + +val point1 = new Point +point1.x = 99 +point1.y = 101 // 경고가 출력됩니다 +``` +이 버전의 `Point` 클래스에서는 데이터가 private 변수 `_x`와 `_y`에 저장됩니다. 이 private 데이터에 접근하기 위한 메서드 `def x`와 `def y`가 있고, `_x`와 `_y` 값을 검증하고 설정하기위한 `def x_=`와 `def y_=`가 있습니다. setter 메서드를 위한 특별한 문법에 주목하십시오: getter 메서드 식별자에 `_=`를 덧붙이고 매개변수가 뒤따르는 형식입니다. + +기본 생성자에서 `val`와 `var`로 지정된 매개변수는 public 입니다. `val`은 불변을 의미하기 때문에 다음의 예처럼 값을 변경할 수 없습니다. +``` +class Point(val x: Int, val y: Int) +val point = new Point(1, 2) +point.x = 3 // <-- 컴파일되지 않습니다 +``` + +`val` 또는 `var`로 지정되지 않은 매개변수는 private 값이므로 클래스 내에서만 참조가능합니다. +``` +class Point(x: Int, y: Int) +val point = new Point(1, 2) +point.x // <-- 컴파일되지 않습니다 +``` diff --git a/_ko/tour/tour-of-scala.md b/_ko/tour/tour-of-scala.md index 422fc2a015..0c83ea5e0c 100644 --- a/_ko/tour/tour-of-scala.md +++ b/_ko/tour/tour-of-scala.md @@ -1,18 +1,12 @@ --- layout: tour title: 들어가며 -discourse: true partof: scala-tour num: 1 +language: ko next-page: basics - -redirect_from: "/tutorials/tour/tour-of-scala.html" - -next-page: basics - -language: ko --- ## 투어를 환영합니다 @@ -32,7 +26,7 @@ language: ko 또한, 스칼라의 패턴 매칭 개념은 [추출자 오브젝트](extractor-objects.html)를 이용한 일반적인 확장으로 [우측 무시 시퀀스 패턴](regular-expression-patterns.html)의 도움을 받아 XML 데이터의 처리까지 자연스럽게 확장됩니다. 이런 맥락에서 [for 컴프리헨션](for-comprehensions.html)은 쿼리를 만들어 내는데 유용합니다. 이런 기능 덕분에 스칼라는 웹 서비스와 같은 애플리케이션 개발에 있어서 이상적인 선택이 될 수 있습니다. ## 스칼라는 정적 타입이다 ## -스칼라는 컴파일 시간에 안전하고 일관성 있는 추상화를 강제하는 풍부한 타입 시스템을 갖추고 있습니다. 타입 시스템은 다음을 지원합니다. +스칼라의 표현형(expressive) 타입 시스템은 컴파일 시간에 안전하고 일관된 방식의 추상화를 사용하도록 강제합니다. 타입 시스템은 다음을 지원합니다: * [제네릭 클래스](generic-classes.html) * [가변성 어노테이션](variances.html) diff --git a/_ko/tour/traits.md b/_ko/tour/traits.md index ef521d2588..655a5557b3 100644 --- a/_ko/tour/traits.md +++ b/_ko/tour/traits.md @@ -8,38 +8,73 @@ language: ko next-page: tuples previous-page: classes +prerequisite-knowledge: expressions, classes, generics, objects, companion-objects --- -트레잇은 자바의 인터페이스와 유사하며, 지원되는 메소드의 서명을 지정해 객체의 타입을 정의하는 데 사용한다. 자바와는 달리, 스칼라에선 트레잇의 일부만 구현할 수도 있다. 다시 말해, 일부 메소드를 선택해 기본 구현 내용을 사전에 정의할 수 있다. 클래스와는 달리, 트레잇은 생성자 파라미터를 가질 수 없다. -다음의 예를 살펴보자. - - trait Similarity { - def isSimilar(x: Any): Boolean - def isNotSimilar(x: Any): Boolean = !isSimilar(x) - } - -이 트레잇은 `isSimilar`와 `isNotSimilar`라는 두 메소드로 구성된다. 메소드 `isSimilar`의 구현은 제공되지 않지만(자바의 abstract와 같다), 메소드 `isNotSimilar`에선 실제로 구현 내용을 정의하고 있다. 그 결과, 이 트레잇과 결합되는 클래스는 오직 `isSimilar`의 실제 구현만을 제공하면 된다. `isNotSimilar`의 행위는 트레잇에서 바로 상속받는다. 일반적으로 트레잇은 [믹스인 클래스 컴포지션](mixin-class-composition.html)을 통해 [클래스](classes.html)(또는 또 다른 트레잇)와 결합된다. - - class Point(xc: Int, yc: Int) extends Similarity { - var x: Int = xc - var y: Int = yc - def isSimilar(obj: Any) = - obj.isInstanceOf[Point] && - obj.asInstanceOf[Point].x == x - } - object TraitsTest extends App { - val p1 = new Point(2, 3) - val p2 = new Point(2, 4) - val p3 = new Point(3, 3) - println(p1.isNotSimilar(p2)) - println(p1.isNotSimilar(p3)) - println(p1.isNotSimilar(2)) - } - -이 프로그램의 실행 결과는 다음과 같다. - - false - true - true - -윤창석, 이한욱 옮김 +트레잇은 클래스간에 인터페이스와 필드를 공유하는 데 사용됩니다. 그것들은 자바8의 인터페이스와 유사합니다. 클래스와 객체는 트레잇을 확장 할 수 있지만 트레잇을 인스턴스화 할 수 없으므로 매개 변수가 없습니다. + +# 트레잇 정의 +가장 단순한 트레잇 정의는 예약어 `trait`과 식별자만 있는 것입니다: + +```tut +trait HairColor +``` + +트레잇은 제네릭 타입과 추상 메서드로 특히 유용합니다. +```tut +trait Iterator[A] { + def hasNext: Boolean + def next(): A +} +``` + +`trait Iterator[A]`를 확장하려면 `A` 타입 지정과 `hasNext`, `next` 메서드 구현이 필요합니다. + +## 트레잇 사용하기 +`extends` 예약어를 사용하여 트레잇을 확장하십시오. 그런 다음 `override` 예약어를 사용하여 트레잇의 추상 멤버를 구현하십시오: +```tut +trait Iterator[A] { + def hasNext: Boolean + def next(): A +} + +class IntIterator(to: Int) extends Iterator[Int] { + private var current = 0 + override def hasNext: Boolean = current < to + override def next(): Int = { + if (hasNext) { + val t = current + current += 1 + t + } else 0 + } +} + + +val iterator = new IntIterator(10) +iterator.next() // returns 0 +iterator.next() // returns 1 +``` +이 `IntIterator` 클래스는 상한선으로 매개변수 `to`를 취합니다. `extends Iterator[Int]`는 트레잇 `Iterator[A]`를 확장했으며 `next` 메서드는 Int 값을 반환해야 한다는 의미입니다. + +## 서브타이핑 +특정 트레잇이 필요한 곳에 그 트레잇의 서브타입을 대신 사용할 수 있습니다. +```tut +import scala.collection.mutable.ArrayBuffer + +trait Pet { + val name: String +} + +class Cat(val name: String) extends Pet +class Dog(val name: String) extends Pet + +val dog = new Dog("Harry") +val cat = new Cat("Sally") + +val animals = ArrayBuffer.empty[Pet] +animals.append(dog) +animals.append(cat) +animals.foreach(pet => println(pet.name)) // Prints Harry Sally +``` +`trait Pet`에는 Cat과 Dog의 생성자에서 구현된 추상 필드 `name`이 있습니다. 마지막 줄에서 `pet.name`을 호출하고 있는데, 이것은 트레잇 `Pet`의 서브타입에서 구현되어야 합니다. diff --git a/_ko/tour/unified-types.md b/_ko/tour/unified-types.md index 4f47c9264b..3b13b95978 100644 --- a/_ko/tour/unified-types.md +++ b/_ko/tour/unified-types.md @@ -8,38 +8,74 @@ language: ko next-page: classes previous-page: basics + +prerequisite-knowledge: classes, basics --- -자바와는 달리, 스칼라에선 모든 값이 객체다(숫자 값과 함수를 포함해). 스칼라는 클래스 기반이기 때문에 모든 값은 클래스의 인스턴스다. 다음의 다이어그램은 클래스 계층구조를 나타낸다. - -![스칼라 타입 계층구조]({{ site.baseurl }}/resources/images/classhierarchy.img_assist_custom.png) - -## 스칼라 클래스 계층구조 ## - -모든 클래스의 슈퍼클래스인 `scala.Any`로부터 `scala.AnyVal`과 `scala.AnyRef`라는 두 서브클래스가 파생되며, 이 두 클래스는 각각 값 클래스와 참조 클래스를 대표한다. 모든 값 클래스는 미리 정의돼 있으며, 이는 자바와 같은 언어의 원시 타입에 해당한다. 다른 모든 클래스는 참조 타입으로 정의된다. 사용자 정의 클래스는 자동으로 참조 타입으로 정의되며, 이렇게 정의된 클래스는 항상 `scala.AnyRef`의 서브클래스(간접적)다. 스칼라의 모든 사용자 정의 클래스는 암시적으로 트레잇 `scala.ScalaObject`를 확장하고 있다. 스칼라가 실행되는 인프라(예, 자바 런타임 환경) 상의 클래스는 `scala.ScalaObject`를 확장하지 않는다. 스칼라를 자바 런타임 환경의 측면에 맞춰 생각해보자면 , `scala.AnyRef`는 `java.lang.Object`에 해당한다. 위의 다이어그램에는 값 클래스 사이의 암시적 변환을 의미하는 뷰도 함께 표현돼 있다. -다음은 다른 객체처럼 숫자와 문자와 불리언 값과 함수 또한 객체임을 보여주는 예제다. - - object UnifiedTypes extends App { - val set = new scala.collection.mutable.LinkedHashSet[Any] - set += "This is a string" // 문자열을 추가한다 - set += 732 // 숫자를 추가한다 - set += 'c' // 캐릭터를 추가한다 - set += true // 불리언 값을 추가한다 - set += main _ // 메인 함수를 추가한다 - val iter: Iterator[Any] = set.iterator - while (iter.hasNext) { - println(iter.next.toString()) - } - } - -이 프로그램은 `App`을 확장한 최상위 싱글턴 오브젝트로써 애플리케이션 `UnifiedTypes`를 선언했다. 애플리케이션에선 클래스 `LinkedHashSet[Any]`의 인스턴스를 가리키는 지역 변수 `set`을 정의했다. 프로그램은 이 집합에 여러 항목을 추가하는데, 해당 항목은 반드시 선언된 항목의 타입인 `Any`에 맞아야 한다. 마지막에는 모든 항목의 문자열 표현을 출력한다. - -다음은 이 프로그램의 실행 결과다. - - This is a string - 732 - c - true - - -윤창석, 이한욱 옮김 \ No newline at end of file +스칼라에서는 숫자 값과 함수를 포함한 모든 값이 타입을 가지고 있습니다. 다음의 도표는 타입 계층구조를 보여줍니다. + +스칼라 타입 계층구조 + + +## 스칼라 타입 계층구조 ## + +[`Any`](https://www.scala-lang.org/api/2.12.1/scala/Any.html)는 모든 타입들의 슈퍼타입이며 톱타입이라고도 합니다. `Any`에는 `equals`, `hashCode`, `toString` 같은 특정 범용 메서드가 정의되어 있으며 직접적으로 두 개의 서브클래스: `AnyVal`과 `AnyRef`를 가지고 있습니다. + +`AnyVal`은 값 타입을 대표합니다. `Double`, `Float`, `Long`, `Int`, `Short`, `Byte`, `Char`, `Unit`, `Boolean`의 미리 정의된 아홉 개의 값 타입이 있으며 이 타입들은 널 값을 가질 수 없습니다. `Unit`은 의미 없는 정보를 갖는 값 타입입니다. `()`와 같이 문자 그대로 선언 할 수있는`Unit`의 인스턴스는 오직 하나만 있습니다. 모든 함수는 무언가를 반환해야하기 때문에 때때로 `Unit`은 유용한 반환 타입입니다. + +`AnyRef`는 참조 타입을 대표합니다. 값 타입이 아닌 모든 타입은 참조 타입으로 정의됩니다. 스칼라에서 모든 사용자정의 타입은 `AnyRef`의 서브타입입니다. 스칼라가 자바 실행 환경에서 사용된다면 `AnyRef`는 `java.lang.Object`에 해당합니다. + +다음 소스는 문자열 값, 정수 값, 문자 값, boolean 값과 함수 역시 모두 객체로 취급됨을 보여주는 샘플입니다: + +```tut +val list: List[Any] = List( + "a string", + 732, // 정수 값 + 'c', // 문자 값 + true, // boolean 값 + () => "an anonymous function returning a string" +) + +list.foreach(element => println(element)) +``` + +`List[Any]` 타입의 `list` 값을 정의합니다. 이 리스트는 다양한 타입의 원소들로 초기화 되었지만 각각은 `scala.Any`의 인스턴스이므로 리스트에 추가할 수가 있습니다. + +다음은 이 프로그램의 출력 결과입니다. + +``` +a string +732 +c +true + +``` + +## 타입 캐스팅 +값 타입은 다음과 같이 캐스팅할 수 있습니다: +Scala Type Hierarchy + +예제: + +```tut +val x: Long = 987654321 +val y: Float = x // 9.8765434E8 (이 경우 일부 자리수가 소실되었음을 주의) + +val face: Char = '☺' +val number: Int = face // 9786 +``` + +캐스팅은 단방향이며 컴파일되지 않습니다: + +``` +val x: Long = 987654321 +val y: Float = x // 9.8765434E8 +val z: Long = y // 적합하지 않음(캐스팅 불가) +``` + +참조 타입 또한 서브타입에 대하여 캐스트할 수 있습니다. 이것은 투어에서 나중에 다루겠습니다. + +# Nothing과 Null +`Nothing`은 모든 타입의 서브타입이며, 바텀타입이라고도 합니다. `Nothing`은 값이 없음을 의미하는 타입니다. 일반적으로 예외 발생, 프로그램 종료 또는 무한 루프와 같은 비 종료 신호를 보내는 용도로 사용합니다 (즉, 값으로 평가되지 않는 표현식의 타입 또는 정상적으로 반환되지 않는 메소드). + +`Null`은 모든 참조 타입의 서브타입입니다(즉, AnyRef의 모든 서브타입). 예약어 `null`로 식별되는 단일 값을 갖습니다. `Null`은 주로 다른 JVM 언어와의 상호 운용성을 위해 제공되며 스칼라 코드에서는 거의 사용되지 않아야합니다. 우리는 투어에서 나중에 `null`에 대한 대안을 다룰 것입니다. diff --git a/_tour/tour-of-scala.md b/_tour/tour-of-scala.md index 6522f8ea99..13edc1220d 100644 --- a/_tour/tour-of-scala.md +++ b/_tour/tour-of-scala.md @@ -51,7 +51,7 @@ In practice, the development of domain-specific applications often requires doma In many cases, this can be done without using meta-programming facilities such as macros. For example, -* [Implicit classes](https://docs.scala-lang.org/overviews/core/implicit-classes.html) allow adding extension methods to existing types. +* [Implicit classes](/overviews/core/implicit-classes.html) allow adding extension methods to existing types. * [String interpolation](/overviews/core/string-interpolation.html) is user-extensible with custom interpolators. ## Scala interoperates