728x90
🟧코틀린 심화편
📌 [강의] Android 를 위한 Kotlin 문법
람다(Lamda)
//람다함수 - 익명함수
fun main() {
println(sumNumber(1,2))
println(sumTypeNumber(1,2))
println(sumTypeNumberNull(1,2))
println(sumString("나는", " 사과."))
println(sumString2("반드시", " 그렇다"))
}
//람다함수
val sumNumber = {a:Int, b:Int -> a+b}
val sumTypeNumber : (Int, Int) -> Int = {a, b -> a + b}
val sumTypeNumberNull : (Int, Int) -> Int? = {a, b -> null }
val sumString : (String, String) -> String = {a, b -> a+b}
val sumString2 = {a:String, b:String -> a+ b}
고차함수(High-order Function)
[고차함수] 함수 안에 다시 함수가 들어가는 꼴
//고차함수 : 함수 안에 함수가 들어가는 꼴
//f(x) = x
// f(f(x)) = x
fun main() {
sum(1, 2, {a:Int, b:Int -> a+b})
sum(1,2, ::testSum)
highPrintTest(::printTest)
}
fun printTest(str : String) {
println(str)
}
fun highPrintTest( A : (String) -> Unit) { //Unit은 아무것도 리턴 X
A("bbb") //여기에 규격맞는 함수 들어갈 수 있음
}
fun sum(a: Int, b: Int, operation:(Int, Int) -> Int) {
println("$a $b")
println(operation(a,b))
}
fun testSum(a:Int, b:Int) : Int {
return a+b
}
제네릭(Generic)
[제네릭] : 제네릭 타입은 컴파일 시 타입을 체크하므로 담을 타입을 처음부터 지정 X
- 이후에 String 값을 넣든, Int 값을 넣든 작동 O
//제네릭(generic)
//컴파일 시 타입 체크 가능
//타입 캐스팅 필요 X
fun main() {
val box1 = Box1(10)
println(box1.value)
val box2 = Box2("숫자 10")
println(box2.value)
//제네릭은 컴파일 시 타입을 체크하므로
// Int, String 등 제약없이 타입 넣을 수 있음
val box3 = Box3(10)
println(box3.value)
val box4 = Box3("10")
println(box4.value)
//메소드에 적용한 제네릭
println(testFun2("안녕"))
println(testFun2(1))
println(test(4))
}
//클래스에서 제네릭 사용
class Box3<T> (test : T) {
var value = test
}
//메소드에서 제네릭 사용
fun <T> testFun2(a: T) {
println(a)
}
//일반 객체1
class Box1(test : Int ) {
var value = test
}
//일반 객체2
class Box2(test : String) {
var value = test
}
오브젝트(object) 객체
//object 객체 -> 싱글톤 패턴
// 객체를 한 개의 종류만 생성한다
// 즉, 매번 다른 종류의 객체가 아니라 늘 같은 종류의 객체 만듬
fun main() {
val test1 = TestClass()
val test2 = TestClass()
test1.count = 10 //test1 객체의 필드 count만 고쳐짐
println(test1.count)
println(test2.count) //test1, test2의 count 값은 다름
val test3 = testObjClass
val test4 = testObjClass // 이 중 하나만 출력됨
test3.count = 10
println(test3.count)
println(test4.count) //test3, test4 의 count값은 동일
}
//object 객체
object testObjClass {
init {
println("obj 클래스 ")
}
var count = 0
}
//일반 객체
class TestClass{
init{
println("TestClass ")
}
var count = 0
}
fun main() {
val test5 = TestObjectClass()
val test6 = TestObjectClass()
//분명 다른 변수에 참조 중인데
test5.plusBtn()
println(TestObjectClass.number)
test5.plusBtn()
println(TestObjectClass.number)
test6.plusBtn() //여전히 동일한 종류의 객체에 대해 처리하고 있다
println(TestObjectClass.number)
}
class TestObjectClass {
companion object {
var number = 0
}
fun plusBtn() {
number++
}
fun minusBtn() {
number--
}
}
지연 초기화(lateinit / lazy)
- lateinit 사용 이유 : 서버에서 데이터 받아올 일 생길 수 있는데,
서버에서 받아온 데이터를 넣어둘 용도로 여러 변수를 우선 lateinit으로 선언만해놓고
나중에 서버에서 값을 받아왔을 때 해당 변수에 담는 용도로 많이 사용함
fun main() {
//lateinit 변수 : 나중에 초기화할 변수임
//var 변수로 선언하므로 나중에 초기화O. 나중에 초기값 변경도 가능함
lateinit var lateString : String
lateString = "변경처리"
println(lateString )
//lazy
//val 변수로 선언하므로 나중에 초기화해도 중간에 초기값 변경은 불가함
val lazyString : String by lazy {
println("이 친구가 만들어질 때 프린트함")
"lazyTestString"
}
lazyString //사용 시 생성되고 값도 할당됨
println(lazyString)
}
infix function
//infix function
// 중간에 끼워넣어서 사용하는 함수
fun main() {
println(10 sum1 20)
println(20 sum2 30)
println("사과" sum2 "포도")
}
infix fun Int.sum1(num:Int) :Int = this + num
infix fun Int.sum2(num:Int) :Int = this + num
infix fun String.sum2(abc:String) : String {
return this + abc
}
kotlin scope function(let / with / run / apply / also)
//kotlin scope 함수
// let / with / run / apply / also
//let -> null 아닐 때 사용
//with -> 람다 결과 제공하지 않고 컨텍스트 내부에서 함수를 호출
//run -> 객체 초기화와 반환 값 계산 필요할 때 주로 사용
//apply -> 값 반환하지 않고, 객체 구성에 대해 주로 사용
//also -> 객체에 대해 추가적인 작업
fun main() {
val str : String? = "hi"
//let 사용
val length = str?.let { //null 아닐 때만 동작함
println(it)
it.length
}
println(length)
//with 사용
val numbers = mutableListOf("a", "b", "c", "d")
println(numbers.first())
println(numbers.last())
val firstAndLast = with(numbers) {
"${first() } ${last() } "
}
println(firstAndLast )
//run 사용
val service = multiPortService("www.naver.com", 80)
val result1 = service.query(service.prepareRequest() + "to port ${service.port} ")
println(result1)
val result2 = service.run {
port = 8080
query(prepareRequest() + "to port $port ")
}
println(result2)
//apply 사용
val tester2 = Person("Tester2").apply{
age = 21
city = "Busan"
}
println(tester2)
//also 사용
val numbers2 = mutableListOf(1,2,3,4)
numbers2.also {
println("$numbers 여기에서 5를 추가한다. ")
}.add(5)
}
class multiPortService(var url : String, var port : Int) {
fun prepareRequest() : String = "기본 요청 url $url"
fun query(request : String) = "결과 query $request"
}
data class Person(
var name : String,
var age : Int = 0,
var city : String = ""
)
kotlin enum class
// enum 클래스
fun main() {
//일부 사용
println(Direction.NORTH)
//모두 사용
Direction.values().forEach {
println(it)
}
//필터링해서 사용
val direction = Direction.EAST
when(direction) {
Direction.NORTH -> {
println("N")
}
Direction.SOUTH -> {
println("S")
}
Direction.WEST -> {
println("W")
}
Direction.EAST -> {
println( "E")
}
}
val color = Color.RED
when(color) {
Color.RED -> {
println(Color.RED.colorName)
}
Color.GREEN -> {
println(Color.GREEN.colorName)
}
Color.BLUE -> {
println(Color.BLUE.colorName)
}
}
}
//enum 클래스 1
enum class Color (val colorName: String) {
RED("빨강"),
GREEN("초록"),
BLUE("파랑")
}
//enum 클래스 2
enum class Direction {
NORTH, SOUTH, WEST, EAST
}
728x90
'App(앱)_관련 공부 모음 > [문법]_Kotlin(코틀린)' 카테고리의 다른 글
[개념] 코틀린 기본 정리 (0) | 2022.08.12 |
---|---|
Android를 위한 Kotlin 문법 [최종편] (0) | 2022.05.07 |
Android를 위한 Kotlin 문법 [기본편 2] (0) | 2022.05.07 |
Android 를 위한 Kotlin문법 [기본편 1] (0) | 2022.05.07 |
2강. [코틀린 고급 문법] (0) | 2022.03.05 |