jam 블로그

러닝스칼라 2장 - 데이터로 작업하기: 리터럴, 값, 변수, 타입 본문

IT Book Study/러닝 스칼라

러닝스칼라 2장 - 데이터로 작업하기: 리터럴, 값, 변수, 타입

kid1412 2020. 9. 28. 23:06
728x90

 

스칼라에서 값과 변수에 저장된 데이터를 더 이상 사용하지 않으면 자바 가상 머신의 가비지 컬렉션이 자동으로 할당을 취소한다. 직접 할당 취소할 필요도 능력도 없다.

리터럴(literal)

숫자 5, 문자 A, 텍스트 ’Hello, World’처럼 소스 코드에 바로 등장하는 데이터

값 (value)

불변의 타입을 갖는 스토리지 단위이며, 데이터를 저장 - 명시적인 타입이 있어야 하는 것은 아니다, 스칼라 컴파일러가 할당된 데이터를 기반으로 추론한다. => 타입 추론 (type inference) - 코드를 작성하는데 타입 추론은 편하지만 가독성을 떨어뜨리지 않는 범위에서 사용

val <식별자>[: 타입] = <데이터>

변수 (variable)

값을 저장하고 그 값을 가져올 수 있도록 할당되거나 예약된 메모리 공간에 대응하는 유일한 식별자 - 메모리 공간에 예약되어 있는 동안에는 새로운 값을 계속 할당할 수 있다. - 메로리 간의 내용은 동적이며 가변적이다. - 스칼라에서는 관례상 변수보다 값을 선호하는 이유는 값을 사용하면 소스 코드가 안정적이며 예측할 수 있기 때문 - 디버깅이 쉽고 멀티 스레드 코드에서 가변 데이터보다 더 안정적이며 에러 발생 확률이 적어진다.

var <식별자>[: 타입] = <데이터>
  • 타입 추론은 가능하지만 지정된 타입은 바꿀수 없다. (예외로 Double 변수에 Int를 할당하면 Double로 바꿔준다)

명명

  • 이름은 숫자로 시작할수 없다
  • val a.b = 4 는 불가능 하지만 val ‘a.b’ = 4 는 가능하다.
  • 관례상 camel case 를 쓴다.

타입

숫자형 타입

이름 크기 리터럴
Byte 1byte  
Short 2byte  
Int 4byte 5, 0x0f
Long 8byte 5l
Float 4byte 5f
Double 8byte 5d, 5.0
  • 스칼라는 타입 순위에 기반하여 한 타입의 순자를 자동으로 다른 타입으로 전환해준다 => 상향전환
  • 표는 자동 전환 순위대로 정렬한것이다. Byte 타입이 최하위여서 모든 타입으로 전환 가능
  • 높은 순위의 데이터 타입이 더 낮은 순위의 타입으로 자동 전환을 허용하지 않는다.
  • to 으로 수동 전환은 가능

문자열

텍스트의 문자열, 스칼라늬 String은 자바의 String을 기반으로 하며, 여러줄 리터럴(multiline literal) 과 문자열 보간(interpolation)을 추가 - 숫자타입과 마찬가지로 수학 연산자 사용 지원 - 여러줄 String은 입력할때 """ """ 를 사용한다 (이때는 인지 못함) - 문자열 보간

val approx = 355/113f
println(s"PI, using 255/113 is about $approx.")
PI, using 255/113 is about 3.141593

val pepper = "pepper "
println(s"${pepper *3} salt")
pepper pepper pepper  salt

// printf
val item = "apple"
f"I wrote a new $item%.3s today"
I wrote a new app today

정규 표현식

검색 패턴을 나타내는 문자와 구두점으로 이루어진 문자열이다. - java.util.regex.Pattern에 기반 - matches, replaceAll, replaceFrist

정규 표현식으로 값 캡처하기

정규 표현식의 고급 처리 기법을 위해서 r 연산자를 호출하여 문자열을 정규표현식 타입으로 전환하면 된다.

scala> val input = "Enjoying this apple 3.14159 times today"
input: String = Enjoying this apple 3.14159 times today

scala> val pattern= """.* apple ([\d.]+) times .*""".r
pattern: scala.util.matching.Regex = .* apple ([\d.]+) times .*

scala> val pattern(amountText) = input
amountText: String = 3.14159

scala> val amount = amountText.toDouble
amount: Double = 3.14159

참고: https://programmingnote.tistory.com/36

스칼라 타입의 개요

  • Any는 절대 루트로 다은 모든 타입들은 이 루트의 두 자식 노으인 AnyVal, AnyRef의 자식이다.
  • Anyval는 값 타입 (value type)이라 하며 숫자형 타입과 Char, Boolean, Unit 포함
    • 객체로 힙메모리에 할당되거나 JVM 기본값으로 스택에 지역적으로 할당된다
    • AnyVal 이외에는 AnyRef 이며 오직 객체로 힙 메모리에만 할당
  • 최하위 Nothing, Null 타입
    • Nothing은 프로그램 흐름에 영향을 줄 수 있는 연산에서 호환성 있는 반환값을 제공
    • return 키워드는 Nothing 이며 타입으로만 사용하며 인스터스화 할 수 없다.
    • Null은 AnyRef의 서브타입으로 키워드 Null 타입을 제공
    • String변수는 언제라도 null 타입이 될수있고 그 변수는 메모리의 어떤 문자열 인스턴스도 가리키지 않는다.
  • char는 String 타입의 기본이 되는 타입으로 단일 문자
    • 다르 숫자와 양방향 전환이 가능하다.
  • Boolean 타입은 true와 false
    • 스칼라는 다른 타입을 부울 타입으로 자동 전환해주지 않는다.
    • null이 아닌 문자열을 true 라고 하지 않고, 숫자 0은 false 와 다르다.
  • Unit은 데티어 타입을 나타내는 대신 데이터가 없음을 나타낸다.
    • void 와 유사하고 () 로 표현

타입 연산

Name Example 설명
asInstanceOf[타입>] 5.asInstanceOf[Long] 해당값을 원하는 타입의 값으로 전환, 그 값이 새로운 타입과 호환되지 않으면 에러
getClass (7.0/5).getClass 해당값의 타입 반환
isInstanceOf (5.0).isInstanceOf[Float] 해당 값이 주어진 타입을 가지면 true 반환
hashCode "A".hashCode 해당 값의 해시값 반환
to<타입> 20.toByte 하나의 값을 호환되는 값으로 반환
toString (3.0/ 4.0).toString 해당 값을 String으로 전환
  • asInstanceOf는 요청받은 타입으로 전환될 수 없으면 에러가 발생한다.
    • 런타입 에러가 발생하는 것을 피하기 위해서는 가능하다면 타입 지정된 전환 연산인 to을 사용하는 것이 좋다.

튜플

둘 이상의 값을 가지는 순서가 있는 컨테이너, 각각의 값은 서로 다른 타입을 가질 수 있다. - 항목은 1부터 시작하는 인덱스를 이용하여 접근가능 , 화살표 연산자로 사용하는 방법

appendix. 그외 이슈

tuple은 왜 loop 순회 할 수 없는가?

  • 튜플은 Tuple case클래스와 product trait으로 구성
  • tuple/product는 item개수에 따라 직접 구현됨
  • product는 내부에 item에 매핑되는 member를 가지고 있음 product구성
  • 각 member는 productElement(n: Int)로 조회될 수 있음
  • product는 productElement를 loop 호출하는 productIterator를 가지고 있음
  • 이것을 사용하여 loop 순회 가능

python의 속도

Comments