분류 전체보기 121

아이템12) 연산자 오버로드를 할 때는 의미에 맞게 사용하라

이펙티브 코루틴을 요약한 내용입니다 연산자 오버로딩은 강력한 기능이지만 ‘큰 힘에는 큰 책임이 따른다’라는 말처럼 위험할 수 있음 연산자 오버로딩의 매력 fun Int.factorial(): Int = (1..this).product() fun Iterable.product(): Int = fold(1) { acc, i -> acc * i } Int 확장 함수로 정의되어 있으므로, 편리하게 사용할 수 있음 print(10 * 6.factorial()) // 7200 연산자 오버로딩을 활용하면 !기호로 팩토리얼을 표현할수 있음 이렇게 사용하면 안됨 operator fun Int.not() = factorial() print(10 * !6) // 7200 함수의 이름이 not이므로 논리 연산에 사용해야지, ..

아이템11) 가독성을 목표로 설계하라

이펙티브 코루틴을 요약한 내용입니다 개발자가 어떤 코드를 작성하는 것보다 읽는 데 많은 시간을 소모한다 오류를 찾기 위해 코드를 작성할 때보다 오랜 시간 코드를 읽게 됨 프로그래밍은 쓰기보다 읽기가 중요함 항상 가독성을 생각하면서 코드를 작성 인식 부하 감소 가독성은 사람에 따라 다르게 느낄 수 있음 일반적으로 ‘경험’과 ‘인식에 대한 과학’으로 만들어진 어느 정도의 규칙이 있음 // 구현 A if (person != null && person.isAudult) { view.showPerson(person) } else { view.showError() } // 구현 B person?.takeIf { it.isAdult } ?.let(view::showPerson) ?: view.showError() A..

아이템10) 단위 테스트를 만들어라

이펙티브 코루틴을 요약한 내용입니다 코드를 안전하게 만드는 가장 궁극적인 방법은 다양한 종류의 테스트를 하는 것 이런 종류의 테스트는 사용자 관점에서 테스트 개발자에게 유용하지만 충분하지는 않음 개발시점에 빠른 피드백을 받기 위해서는 피보나치 숫자 5개를 제대로 구하는지 확인하는 테스트 @Test fun `fib works correnctly for the first 5 positions`() { assertEquals(1, fib(0)) assertEquals(1, fib(1)) assertEquals(2, fib(2)) assertEquals(3, fib(3)) assertEquals(5, fib(4)) } 단위 테스트에서 확인할 부분 일반적인 유스 케이스: 요소가 사용될 거라고 예상되는 일반적인 방..

아이템9) use를 사용하여 리소스를 닫아라

이펙티브 코루틴을 요약한 내용입니다 더 이상 필요하지 않을 때, close 메서드를 사용해서 명시적으로 닫아야 하는 리소스가 있음 InputStream, OutputStream java.sql.Connection java.io.Reader(FileReader, BufferedReader, CSSParser) java.new.Socket, java.util.Scanner AutoCloseable을 상속받은 Closeable 인터페이스를 구현하고 있음 모든 리소스는 최종적으로 리소스에 대한 레퍼런스가 없어질 때 가비지 컬렉터가 처리 굉장히 느리며 리소스를 유지하는 비용이 많이 발생 명시적으로 close를 호출하는 것이 좋음 try-catch fun coutCharactersInFile(path: String..

아이템8) 적절하게 null을 처리하라

이펙티브 코루틴을 요약한 내용입니다 함수가 null을 리턴한다는 것은 함수에 다라 여러 의미를 가질 수 있음 String.toIntOrNull()은 String을 Int로 적절하게 변환할 수 없는 경우 null 리턴 Iterable.firstOrNull(() → Boolean) 은 주어진 조건에 맞는 요소가 없을 경우 null 리턴 null은 최대한 명확한 의미를 갖는 것이 좋음 val printer: Printer? = getPrinter() printer.print() // 오류 printer?.print() // 안전한 호출 if (printer != null) printer.print() // 스마트 캐스팅 printer!!.print() // not-null assertion nullable 타..

아이템7) 결과 부족이 발생한 경우 null과 Failure를 사용하라

이펙티브 코루틴을 요약한 내용입니다 함수가 원하는 결과를 만들어 낼 수 없을 때 서버로부터 데이터를 읽어 들이려고 했는데, 인터넷 연결 문제로 읽어 들이지 못한 경우 조건에 맞는 첫 번째 요소를 찾으려 했는데, 조건에 맞는 요소가 없는 경우 텍스트를 파싱해서 객체를 만들려고 했는데, 텍스트의 형식이 맞지 않은 경우 원하는 결과를 만들어 낼 수 없을 때 처리 메커니즘 null 또는 ‘실패를 나타내는 sealed 클래스(Failure 이름을 붙임)`를 리턴 예외를 throw 예외는 정보를 전달하는 방법으로 사용해서는 안됨 예외는 잘못된 특별한 상황을 나타내야 함 예외는 예외적인 상황이 발생했을 때 사용하는 것이 좋음 예외는 예외적인 상황이 발생되었을 때 사용 - 이팩티브 자바의 내용 예외가 전파되는 과정을 ..

아이템6) 사용자 정의 오류보다는 표준 오류를 사용하라

이펙티브 코루틴을 요약한 내용입니다. require, check, assert 함수를 사용하면 대부분의 코틀린 오류를 처리할 수 있음 예측하지 못한 상황을 나타내야 하는 경우가 있음 ex) JSON 형식을 파싱하는 라이브러리의 오류 가능한 JSONParsingException을 발생하는 것이 좋음 inline fun String.readObject(): T { if (incorrectSign) { throw JSONParsingException() } return result } 표준 라이브러리에는 적절한 오류가 없으므로 사용자 정의 오류를 사용 가능하다면, 직접 오류를 정의하는 것보다는 최대한 표준 라이브러리의 오류를 사용하는 것이 좋음 많은 개발자가 알고 있으므로 재사용하는 것이 좋음 일반적으로 사용..

아이템5) 예외를 활용해 코드에 제한을 걸어라

이펙티브 코루틴을 요약한 내용입니다. 예외를 활용해 제한을 걸어주는 것이 좋음 코틀린에서 코드의 동작에 제한을 걸 때 다음과 같은 방법을 사용할 수 있음 require 블록: 아규먼트를 제한할 수 있음 check 블록: 상태와 관련된 동작을 제한할 수 있음 assert 블록: 어떤 것이 true인지 확인 가능 assert 블록은 테스트 모드에서만 동작 return 또는 throw와 함께 활용하는 Elvis 연산자 사용 예제 제한을 걸면 문서를 읽지 않은 개발자도 문제를 확인할 수 있음 문제가 있을 경우에 함수가 예상하지 못한 동작을 하지 않고 예외를 발생 코드가 어느 정도 자체적으로 검사를 함 스마트 캐스트 기능을 활용할 수 있음 fun pop(num: Int = 1): List { require(num..

아이템4) inferred 타입으로 리턴하지 말라

이펙티브 코루틴을 요약한 내용입니다. 코틀린의 타입 추론은 JVM 세계에서 가장 널리 알려진 특징 Java 10부터 타입 추론이 도입되었지만 제약 사항이 있음 타입 추론을 사용할 때 몇가지 위험한 부분이 있음 inferred 타입은 정화하게 오른쪽에 있는 피연산자에 맞게 설정 슈퍼클래스 또는 인터페이스로는 설정 되지 않음 open class Aniaml class Zebra: Animal() fun main() { var animal = Zebra() animal = Animal() } 타입을 명시적으로 지정해서 문제를 해결 open class Aniaml class Zebra: Animal() fun main() { var animal: Aniaml = Zebra() animal = Animal() }..

아이템3) 최대한 플랫폼 타입을 사용하지 말라

이펙티브 코루틴을 요약한 내용입니다. null-safety는 코틀린의 주요 기능 중 하나 자바에서 String 타입을 리턴하는 메서드의 경우 nullable로 처리 해야할까? @Nullable 어노테이션이 있다면 nullable로 추정 @NotNull 어노테이션이 있다면 String 으로 변경 어노테이션이 없다면 nullable로 가정하고 다루는 것이 좋음 not-null을 단정할 수 있다면 !!를 사용 nullable과 관련하여 자주 문제가 되는 부분은 자바의 제네릭 타입 List를 리턴하는 경우 리스트와 리스트 내부의 User 객체들이 널이 아닌 것을 알아야 함 public class UserRepo { public List getUsers() { } } val users: List = UserRep..