본문 바로가기

분류 전체보기

(386)
CH6(6.2). 코틀린의 원시 타입 1. 원시 타입: Int, Boolean 등 - 원시 타입의 변수에는 그 값이 직접 들어가지만, 참조 타입의 변수에는 메모리상의 객체의 위치가 들어간다. 자바는 참조 타입이 필요한 경우 특별한 래퍼 타입으로 원시타입 값을 감싸서 사용한다. 원시 타입의 값에 대해 메소드를 호출하거나 컬렉션에 담을 수 없기때문에 Collection 등으로 래퍼 타입으로 감싸서 사용한다. 코틀린은 원시 타입과 래퍼 타입을 구분하지 않으므로 항상 같은 타입을 사용한다. - 코틀린에서는 숫자 타입 등 원시 타입의 값에 대해 메소드를 호출할 수 있다. fun showProgress(progress: Int){ val percent = progress.coerceIn(0, 100) println("We are $percent% do..
[c++] 백준 1019 책 페이지 [문제] https://www.acmicpc.net/problem/1019 1019번: 책 페이지 첫째 줄에 0이 총 몇 번 나오는지, 1이 총 몇 번 나오는지, ..., 9가 총 몇 번 나오는지를 공백으로 구분해 출력한다. www.acmicpc.net [풀이] 먼저 [A, B] 사이에 0~9가 등장한 횟수를 세는 것으로 생각해야 한다. A의 1의 자리가 0이고 B의 1의 자리가 9라면 그 사이에 0~9가 등장한 횟수는 공통적으로 B/10-A/10+1이 된다. 예를 들어, [22, 315] 라고 하면 처음 1의 자리가 0이 될 때까지 A를 증가시킨다. 이때의 값은 직접 계산해준다. 마찬가지로 B의 1의 자리가 9가 될 때까지 감소시켜주고, 그때까지의 횟수는 직접 계산한다. [30, 309]가 되면 30~..
CH6(6.1-2). 널 가능성 1. 나중에 초기화할 프로퍼티 - 객체 인스턴스를 일단 생성한 다음에 나중에 초기화하는 프레임워크가 많다. 하지만 코틀린에서는 클래스 안의 널이 될 수 없는 프로퍼티를 생성자 안에서 초기화하지 않고 특별한 메소드 안에서 초기화할 수는 없다. 일반적으로는 생성자에서 모든 프로퍼티를 초기화하며, 만약 프로퍼티 타입이 널이 될 수 없는 타입이라면 반드시 널이 아닌 값으로 초기화해야 한다. 그럴 수 없다면 널이 될 수 있는 타입을 제공해야 하거, 이 경우 모든 프로퍼티 접근에 널 검사를 넣거나 !!를 넣어야하므로 보기 나쁜 코드가 된다. - lateinit 변경자를 붙이면 프로퍼티를 나중에 초기화할 수 있다. class MyService{ fun performAction():String = "action" } ..
CH6(6.1-1). 널 가능성 1. 널이 될 수 있는 타입 - 코틀린과 자바의 가장 중요한 차이는 코틀린 타입 시스템이 널이 될 수 있는 타입을 지원한다는 점이다. 자바에서는, 어떤 변수가 널이 될 수 있다면 그 변수에 대해 메소드를 호출할 시 NullPointerException이 발생할 수 있으므로 안전하지 않다. 코틀린은 그런 메소드 호출을 금지함으로써 많은 오류를 방지한다. (NPE의 경우 런타임 시 발생하지만, 코틀린에서는 컴파일 시 오류를 발생시킨다.) - strLen 함수의 경우 파라미터 s의 타입인 String이 널로 넘어오지 못하게 컴파일 오류를 발생시킨다. 이 함수가 널과 문자열을 인자로 받을 수 있게 하려면 타입 이름 뒤에 물음표(?)를 명시해야 한다. fun strLenSafe(s:String?) = ... ty..
CH5(5.5). 수신 객체 지정 람다 1. with 함수 fun alphabet(): String { val result = StringBuilder() for(letter in 'A'..'Z'){ result.append(letter) } result.append("\nNow I know the alphabet!") return result.toString() } >>>println(alphabet()) ABCDE....XYZ Now I know the alphabet! 위의 예제에서는 result에 대해 다른 여러 메소드를 호출하면서 매번 result를 반복 사용했다. 이 예제를 with로 다시 작성한 결과는 다음과 같다. fun alphabet(): String { val stringBuilder = StringBuilder() ret..
CH5(5.3). 지연 계산 컬렉션 연산 1. 지연 계산 컬렉션 연산 - map이나 filter 같은 함수들은 결과 컬렉션을 즉시 생성한다. 이는 컬렉션 함수를 연쇄하면 매 단계마다 계산 중간 결과를 새로운 컬렉션에 임시도 담는다는 뜻이다. 시퀀스를 사용하면 중간 임시 컬렉션을 사용하지 않고도 컬렉션 연산을 연쇄할 수 있다. people.map(Person::name).filter{ it.startWith("A") } -코틀린 표준 라이브러리 참조 문서에는 filter와 map이 리스트를 반환한다고 써 있다. 이는 이 연쇄 호출이 리스트를 2개 만든다는 뜻이다. 한 리스트는 filter의 결과를 담고, 다른 하나는 map의 결과를 담는다. 만약 원소가 수백만개가 되면 효율이 떨어질 것이다. 이를 효율적으로 하기 위해서는 각 연산이 컬렉션을 직접..
CH5(5.2). 컬렉션 함수형 API 1. filter와 map - filter 함수는 컬렉션을 이터레이션하면서 주어진 람다에 각 원소를 넘겨서 람다가 true를 반환하는 원소만 모은다. >>> val list = listOf(1,2,3,4) >>> println(list.filter { it%2 == 0 }) [2,4] - map 함수는 주어진 람다를 컬렉션의 각 원소에 적용한 결과를 모아서 새 컬렉션을 만든다. >>>val list = listOf(1,2,3,4) >>>println(list.map{ it*it }) [1,4,9,16] 2. all, any, count, find - 컬렉션의 모든 원소가 어떤 조건을 만족하는지 판단하는 연산이다. val canBeInClub27 = {p:Person -> p.age>> val people..
CH5(5.1). 람다 식과 멤버 참조 1. 람다 소개 - 함수형 프로그래밍에서는 함수를 값처럼 다루는 방식을 통해 코드를 함수에 넘기거나 변수에 저장할 수 있게 한다. 클래스를 선언하고 그 클래스의 인스턴스에 함수를 넘기는 대신, 함수형 언어에서는 함수를 직접 다른 함수에 전달할 수 있다. 람다 식을 이용하면 함수를 선언할 필요가 없고 코드 블록을 직접 함수의 인자로 전달할 수 있다. 2. 람다와 컬렉션 - 람다를 사용해 컬렉션 검색하기 >>> val people = listOf(Person("Alice", 29), Person("Bob", 31)) >>> println(people.maxBy{ it.age }) Person(name=Bob, age=31) maxBy는 가장 큰 원소를 찾기 위해 비교에 사용할 값을 돌려주는 함수를 인자로 받..