일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 안드로이드 레트로핏 사용법
- 스택 큐 차이
- 큐 자바 코드
- jvm 작동 원리
- android retrofit login
- 플러터 설치 2022
- jvm이란
- 안드로이드 라이선스
- 안드로이드 유닛 테스트
- 클래스
- 객체
- Rxjava Observable
- 서비스 vs 쓰레드
- ar vr 차이
- 2022 플러터 안드로이드 스튜디오
- 안드로이드 os 구조
- 자바 다형성
- rxjava cold observable
- 2022 플러터 설치
- 안드로이드 라이선스 종류
- 멤버변수
- 안드로이드 유닛테스트란
- 스택 자바 코드
- 안드로이드 유닛 테스트 예시
- ANR이란
- 서비스 쓰레드 차이
- rxjava hot observable
- 안드로이드 레트로핏 crud
- android ar 개발
- rxjava disposable
- Today
- Total
목록책/Effective Kotlin (53)
나만을 위한 블로그
채용 인터뷰에서 필자의 친구는 "함수에서 Unit?을 리턴한다면 그 이유는 무엇인가?" 라는 질문을 받았다. Boolean이 T/F를 갖는 것처럼 Unit?은 Unit 또는 null이란 값을 가질 수 있다. 따라서 Boolean과 Unit? 타입은 서로 바꿔서 사용할 수 있다. 일반적으로 Unit?을 사용한다는 건 이런 경우다. fun keyIsCorrect(key: String): Boolean { //... } fun main() { if (!keyIsCorrect(key = "key")) return } 다음 코드처럼 사용할 수도 있다. fun verifyKey(key: String): Unit? { // ... } fun main() { verifyKey(key = "key") ?: return ..
예를 들어 팩토리얼을 구하는 함수를 생각해 본다. fun Int.factorial(): Int = (1..this).product() fun Iterable.product(): Int = fold(1) { acc, i -> acc * i } 이 함수는 Int 확장 함수로 정의돼 있어 편하게 쓸 수 있다. fun main() { print(10 * 6.factorial()) // 7200 } 팩토리얼은 ! 기호를 써서 표기하지만 코틀린은 이런 연산자를 지원하지 않는다. 그러나 아래처럼 연산자 오버로딩을 활용하면 만들 수 있다. // not() = "!" 기호 operator fun Int.not() = factorial() fun main() { print(10 * !6) // 7200 } 이렇게 할 수는..
개발자가 코드를 작성하는 데는 1분 걸리지만 읽는 데는 10분이 걸린다는 말이 있다. 즉 개발자는 어떤 코드를 작성하는 것보다 읽는 데 많은 시간을 소모한다는 것이다. 오류를 찾기 위해 코드를 칠 때마다 오랜 시간 코드를 읽는 자신을 발견할 수 있을 것이다. 프로그래밍은 쓰기보다 읽기가 중요하다는 의미다. 따라서 항상 가독성을 생각하며 코드를 작성해야 한다. 인식 부하 감소 가독성은 사람에 따라 다르게 느낄 수 있다. 하지만 일반적으로 많은 사람들의 경험, 인식에 대한 과학으로 만들어진 어느 정도의 규칙이 있다. 아래 코드를 확인하자. fun main() { // 구현 A if (person != null && perso.isAdult) { view.showPerson(person) } else { vi..
코드를 안전하게 만드는 궁극적인 방법은 다양한 종류의 테스트를 하는 것이다. 이런 종류의 테스트는 개발자 관점에서 앱 내부적으로 올바르게 작동하는지 확인하는 게 아니라 사용자 관점에서 앱 외부적으로 제대로 작동하는지 확인하는 게 목표다. 이런 테스트는 개발자에게 유용하지만 충분하진 않다. 이것만으론 해당 요소가 올바르게 작동한다는 걸 완전하게 보증할 수는 없다. 또한 개발 시점에서 빠른 피드백을 받을 수 없다. 이런 문제를 해결하려면 단위 테스트가 필요하다. 이것은 개발자가 작성하며 개발자에게 유용하다. 단위 테스트는 일반적으로 아래 내용들을 확인한다. 일반적인 유스 케이스(happy path) : 요소가 사용될 거라 예상되는 일반적인 방법을 테스트한다. 앞의 코드처럼 함수로 간단한 숫자 몇 개를 테스트..
더 이상 필요하지 않을 때 close()를 써서 명시적으로 닫아야 하는 리소스가 있다. Input/OutputStream java.sql.Connection java.io.Reader(FileReader, BufferedReader, CSSParser) java.new.socket, java.util.Scanner 이런 리소스들은 AutoCloseable을 상속받는 Closeable 인터페이스를 구현하고 있다. 이런 모든 리소스는 최종적으로 리소스에 대한 레퍼런스가 없어질 때 가비지 컬렉터가 처리하지만 굉장히 느리고 그 동안리소스를 유지하는 비용이 많이 들어간다. 따라서 더 이상 필요없다면 명시적으로 close()를 호출하는 게 좋다. 전통적으로 이런 리소스는 try-catch 블록을 써서 처리한다. f..
null : 값이 부족하다(lack of value) 프로퍼티가 null = 값이 설정되지 않았거나 제거됐음을 나타냄 함수가 null을 리턴하는 건 함수에 따라 여러 의미를 가질 수 있다. String.toIntOrNull() : String -> Int로 적절하게 변환할 수 없을 경우 null 리턴 Iterable.firstOrNull(() -> Boolean) : 주어진 조건에 맞는 요소가 없을 경우 null 리턴 null은 최대한 명확한 의미를 갖는 게 좋다. nullable 값을 처리해야 하기 때문인데 이걸 처리하는 사람은 API 사용자(API 요소를 사용하는 개발자)다 val printer: Printer? = getPrinter() printer.print() // 컴파일 오류 printer?..
함수가 원하는 결과를 만들어 낼 수 없을 때가 있다. 서버에서 데이터를 읽어 들이려고 했는데 인터넷 연결 문제로 그러지 못한 경우 조건에 맞는 첫 번째 요소를 찾으려 했는데 없는 경우 텍스트를 파싱해서 객체를 만들려고 했는데 텍스트 형식이 맞지 않는 경우 이런 상황을 처리하는 매커니즘은 크게 2가지 있다. null 또는 '실패를 나타내는 sealed 클래스(일반적으로 Failure란 이름을 붙임)'를 리턴한다 예외를 throw한다 이 2가지는 중요한 차이가 있다. 예외는 정보를 전달하는 방법으로 쓰여선 안 된다. 예외는 잘못된 특별한 상황을 나타내야 하며 처리돼야 한다. 예외는 예외적인 상황이 발생했을 때 사용하는 게 좋다. 이 이유를 정리하면 아래와 같다. 많은 개발자가 예외가 전파되는 과정을 제대로 ..
require, check, assert 함수를 쓰면 대부분의 코틀린 오류를 처리할 수 있다. 하지만 이외에도 예측하지 못한 상황을 나타내야 하는 경우가 있다. 예를 들어 입력된 JSON 파일 형식에 문제가 있다면 JSONParsingException 등을 발생시키는 게 좋을 것이다. inline fun String.readObject(): T { // ... if (incorrectSign) { throw JsonParsingException() } // ... return result } 표준 라이브러리에는 이를 나타내는 적절한 오류가 없으므로 사용자 정의 오류를 사용했다. 하지만 가능하다면 직접 오류를 정의하는 것보다 최대한 표준 라이브러리의 오류를 사용하는 게 좋다. 표준 라이브러리 오류는 많은 ..
확실하게 어떤 형태로 동작해야 하는 코드가 있다면 예외를 활용해 제한을 걸어주는 게 좋다. 코틀린에선 코드 동작에 제한을 걸 때 아래 방법을 쓸 수 있다. require 블록 : 아규먼트를 제한할 수 있다 check 블록 : 상태와 관련된 동작을 제한할 수 있다 assert 블록 : 어떤 게 true인지 확인할 수 있다. assert 블록은 테스트 모드에서만 작동한다 return 또는 throw와 같이 쓰는 Elvis 연산자 아래는 이런 매커니즘을 쓰는 간단한 예시다 fun pop(num: Int = 1): List { require(num = 0) return if (n = 0) { "Cannot calculate factorial of $n because it is smaller than 0" } r..
타입 추론(type inference) : 코틀린 특징 중 하나. 자바도 자바 10부터 코틀린을 따라 타입 추론을 도입했다. 타입 추론을 쓸 때 위험한 부분들이 있다. 할당 시 inferred 타입은 오른쪽 피연산자에 맞게 설정된다. 절대 슈퍼클래스 or 인터페이스로는 설정되지 않는다 open class Animal class Zebra: Animal() fun main() { var animal = Zebra() animal = Animal() // Type mismatch 오류 } 내가 원하는 타입보다 제한된 타입이 설정됐다면 타입을 명시적으로 지정해서 해결하면 된다. open class Animal class Zebra: Animal() fun main() { var animal: Animal = ..