5장 basic types and operations - codeport/scala GitHub Wiki

drypot님의 한글 번역

###5.1 Some basic types

  • integral types : Byte, Short, Int, Long, Char
  • numeric types : integral types + Float, Double
  • java.lang 패키지의 String을 제외한 모든 타입은 scala패키지에 있다.
    • Int는 scala.Int
  • scala 패키지와 java.lang 패키지는 스칼라 소스 파일에 자동으로 import되여서 간단하게 Int만 사용 가능.
  • 스칼라의 기본 타입은 Java의 타입과 범위가 똑같다.
    • 스칼라 컴파일러는 스칼라의 value types을 자바의 primitive types로 변환시킬 수 있다.

###5.2 Literals
모든 기본값은 Literal로 나타낼 수 있다. Literal은 constant value를 코드에 직접쓰는 방법이다. (ex: 1, "One", (x: Int) => x + 1

  • Integer literals
    • Int, Long, Short, Byte 타입에 대한 리터럴
    • decimal, hexadecimal, octal 3가지 형식이 있다.
    • 0x0X로 시작하면 hexadedemical이다.(16진수)
scala> val hex = 0x5
hex: Int = 5
scala> val hex2 = 0x00FF
hex2: Int = 255
scala> val magic = 0xcafebabe
magic: Int = -889275714
- 0으로 시작하면 octal이다.(8진수)
scala> val oct = 035  // (35 octal is 29 decimal)
oct: Int = 29
scala> val nov = 0777
nov: Int = 511
scala> val dec = 0321
dec: Int = 209
- 0이 아닌 숫자로 시작하면 demical이다.(10진수)
scala> val dec1 = 31
dec1: Int = 31
scala> val dec2 = 255
dec2: Int = 255
scala> val dec3 = 20
dec3: Int = 20
- `L`이나 `l`으로 끝나면 Long이다.
scala> val prog = 0XCAFEBABEL
prog: Long = 3405691582
scala> val tower = 35L
tower: Long = 35
scala> val of = 31l
of: Long = 31
  • Floating point literals
    • F나 f로 끝나면 Float고 그렇지 않으면 Double이다.
    • Double 리터럴에 D나 d를 붙힐 수 있다.
scala> val big = 1.2345
big: Double = 1.2345
scala> val bigger = 1.2345e1
bigger: Double = 12.345
scala> val biggerStill = 123E45
biggerStill: Double = 1.23E47
scala> val little = 1.2345F
little: Float = 1.2345
scala> val littleBigger = 3e5f
littleBigger: Float = 300000.0
scala> val anotherDouble = 3e5
anotherDouble: Double = 300000.0
scala> val yetAnother = 3e5D
yetAnother: Double = 300000.0
  • Character literals
    • 따옴표사이에 유니코드 문자로 표시함
    • '\101'로 8진수나 '\u0041'처럼 16진수로 유니코드 표시가능
    • escape로 표현되는 몇몇 character가 있음 val backslash = '\\'
  • String literals
    • 쌍따옴표로 표시한다.
    • 세 따옴표로 여러라인에 걸쳐서 표시할 수 있다.
println("""Welcome to Ultamix 3000.
           Type "HELP" for help.""")
- 중간에 공백을 제거하면 파이프와 `stripMargin`을 사용한다.
println("""|Welcome to Ultamix 3000.
           |Type "HELP" for help.""".stripMargin)
  • Symbol literals
    • 심볼리터럴은 'ident로 작성하고 여기서 ident는 알파벳이다.
    • 이러한 리터럴은 scala.Symbol의 인스턴스와 매핑된다.
    • 'cymbalSymbol("cymbal")를 호출한다.
scala> val s = 'aSymbol
s: Symbol = 'aSymbol
scala> s.name
res20: String = aSymbol
- 같은 심볼리터럴을 두번 사용하면 같은 `Symbol`객체를 참조한다.
  • Boolean literals
    • truefalse가 있다.

###5.3 Operators are methods

  • 1 + 2(1).+(2)이다.
  • 오퍼레이터 노테이션으로 여러 인자를 받으면 항상 괄호를 써야한다.
  • 모든 메서드는 오퍼레이터가 될 수 있다.
    • s.indexOf('o')에서 indexOf는 오퍼레이터가 아니지만 s indexOf 'o'에서 indexOf는 오퍼레이터다.
      • . 빼고 호출하는 형태를 operator notation이라고 하나 봄. (pg 82, 중간 회색 박스)
  • prefix/postfix 연잔사는 unary다. 피연산자를 하나만 받는다.
  • infix 연산자처럼 prefix 연산자는 메서드를 호출한다. 즉 -2.0(2.0).unary_-가 된다.
  • prefix operators +, -, !, ~
    • *의 경우, unary_*를 정의한다고 해도 prefix operator notation으로 사용할 수 없다. prefix operator로 사용될 수 있는 네 가지 identifiers 중에 하나가 아니기 때문이다. 만약에 *p 처럼 호출하려고 한다면 Scala는 이것을 *.p 처럼 해석할 것이지만 그것은 당신이 생각했던 결과는 아닐 것이다.
  • infix: 객체와 매개변수 사이에 메서드가 위치. ex) 3.+(4)
  • prefix: 호출 객체 앞에 메서드가 위치. +, -, !, ~ 만 쓸 수 있음. ex) -7 -> 7.unary_-
  • postfix: 객체 뒤에 메서드가 위치. ex) 7 toLong <- 이건 형태만 보면 인자 없는 infix랑 같지 않나? 설명도 그렇게 나온 듯.

###5.4 Arithmetic operations

  • 산술연산 메소드를 infix 형태로 실행 할수 있다. 더하기 (+), 빼기 (-), 곱하기 (*), 나누기 (/), 나머지 (%) %는 정수의 나누기로 구현
  • IEEE 754 remainder : 부동소수점 숫자에 대해 % 연산자를 실행할 경우, IEEE 754에선 rounding division을 쓴다고 한다. (뭔 소린지?) 하여간 결과가 이렇게 나온다고 함. 근데 쓸 덴 없을 듯.

scala> math.IEEEremainder(11.0 , 4.0) res14: Double = -1.0

  • 부동 소수점에 % 연산자를 호출한 결과 값은 IEEE 754 표준에 정의된 remainder가 아니다. 그래서 정수 %(remainder) operator와 전혀 다른 결과가 나올 것이다.

###5.5 Relational and logical operations

logical-and 와 logical-or 는 자바와 동일하게 short-circuited. 어떻게 이게 가능한가는 Section 9.5의 by-name parameter를 보라고 함. && 도 메서드라면 java 같은 경우 호출 시점에 모든 parameter가 eval되어야 하는데 scala에선 by-name parameter 덕분에 선택적으로 eval할 수 있음.

###5.6 Bitwise operations

scala> 1 & 2 // 비트 AND
res24: Int = 0
scala> 1 | 2 // 비트 OR
res25: Int = 3
scala> 1 ˆ 3 // 비트 XOR
res26: Int = 2
scala> ~1 // 비트 Not 
res27: Int = -2
scala> -1 >> 31 // shift right
res28: Int = -1
scala> -1 >>> 31 // unsigned
res29: Int = 1
scala> 1 << 2 // shift left
res30: Int = 4

###5.7 Object equality 오브젝트의 동등성을 확인하기 위해서 ==!=를 사용할 수 있다.

  1. left side가 null인지 확인 (null 체크를 스칼라가 해줌)
  2. null이 아니면, equal 메소드 호출

Java와 다른 점

  • java의 ==는 참조 동등성이다.
  • 스칼라는 참조 동등성을 위해서 eq를 제공한다. 다만 Java Object에 직접 맵된 경우에만 적용된다(?)

5.8 Operator precedence and associativity

  • OPERATOR PRECEDENCE
  • 연산자 우선순위는 java와 비슷한 듯. 다만 :로 끝나는 연산자의 경우, 우에서 좌로 grouping됨. a:::b:::c -> a:::(b:::c)

5.9 Rich wrappers

implicit conversion을 이용한 다양한 rich wrapper가 제공됨. 야호!