[컴] 내가 주로 사용하는 코틀린의 문법들

class<T> 를 parameter로 / how to pass class as a parameter in kotlin



open

기본적으로 함수는 public 이고 override 에 대해서 close 돼 있다. 그래서 override 를 허락할 함수는 open 을 붙여줘야 한다.

open fun getFragName(): String{
        return "Frag"
    }




type

추측할 수 있는 Type(Class) 는 적지 않아도 된다.


?

? (물음표) 는 type 뒤에 붙어서 null 이 가능한 변수임을 나타낸다. 이녀석이 붙어 있지 않은 녀석은 null 이 되는 경우가 없다는 것을 보장한다. 기존의 java 처럼 NPE(Null pointer Exception) 을 만들고 싶으면 !! 를 사용하면 된다. Null Safety 를 참조하자.

?.



b?.name
이런식으로 사용되는데, 이러면 b 가 null 인 경우에 보통의 경우라면 null 의 property 를 참조하기 때문에 NullPointerException(NPE) 가 발생한다. 그런데 이 경우는 그냥 null 을 return 해 준다. 그냥 java 에서 처럼 NPE 를 발생시키려고 한다면 b!!.name 을 해주면 된다.

?:

b?.name ?: 1
이 그냥 null 을 return 해 준다고 했다. 이녀석이 null 일 때 특정 값을 1 을 return 되게 해준다. null 이 아니라면 당연히 b.name 을 return 한다.


문자열과 달러표시 변수

  • "$variable_name  hi !"
위와 같이 " 안에 $ 로 시작하는 녀석은 변수로 인식한다. java style 로 변경하면
  • variable_name + " hi !"
가 되는 것이다.
참고로 ${variable_name} 으로 사용이 가능하다.
달러표시는 "${'$'}" 이런식으로 하면 된다.


var, val

var : 일반적인 경우, 값이 assign 이후에 새롭게 assign 을 하는 경우라면
val : java 에서 final 을 붙여서 쓸 경우라면


cast

b as String // (String)b
이것을 unsafe cast 라 부르는데, 아래처럼 code 를 작성하면 알아서 Cast 해서 인식한다. (smart Cast)
if(b is String){
  // do with b
}


when 

switch 대신에 when 이 존재한다. 아래처럼 사용할 수 있다.
when (x) {
  1 -> print("x == 1")
  2 -> print("x == 2")
  else -> { 
    print("x is neither 1 nor 2")
  }
}


class 에서 final 이 아닌 일반 private 멤버 변수 선언

var textView :TextView by Delegates.notNull()

var 이 null 이 아닌 경우에는 어떤 값이 assign 되어있어야 하는데, class 의 instantiate 뒤에 assign 되는 경우가 있다. 이럴 때 선언시에 위의 방식을 사용할 수 있다.


for loop

for 에는 in 을 쓴다.

for (i in array.indices)
  print(array[i])




array

// java
String[] a = {"test1", "test2"};

// kotlin
val a = arrayOf("test1", "test2")

val a = arrayOf("test1", "test2")
val a = arrayOf(1, 2)

web page 에서 test

interpreter 처럼 웹페이지에서 사용해 볼 수 있다. : http://try.kotlinlang.org/



open class

kotlin 에서 기본적으로 모든 class 는 final 이다. 그래서 상속이 되지 않는다. 상속을 하고 싶은 class 가 있다면 open 으로 설정하자.


Visibility Modifiers, public...

기본적으로 java 와 같다.



Higher Order Function

함수를 parameter 로 받는 함수를 이야기 하는데, 이녀석을 정의할 수 있다.
fun test(a :Int)
이런것이 일반적인 함수의 모습이면, 여기에 Int 대신에 함수의 모양을 정해주면 된다.
fun test(f : () -> String)
() -> String 은 parameter 가 없고, return 이 String 이 함수 모습을 이야기 한다. 그냥 return 만 할 때는 ()->Unit 을 해주면 된다.

실제 사용할 때는 아래처럼 하면 된다.

fun test(myf : (v: View) -> String)

test(f={ view ->
  view.text = "hello"
  "test" // return
}


return

return 은 literal 에서 return 하는 경우에 조심해야 한다. literal ({} 로만 되어 있는 함수) 에서 return 을 하면, literal 내에서 return 을 하는 것이 아니라, literal 외부의 함수의 scope 에서 return 한다.
literal 내에서 return 은 literal 에 이름을 붙이고, 그 이름에 대해서 return 한다고 알려줘야 한다.
void test(){
  onClick handler@{
     return@handler
  }
}




data class

흔히 간단한 struct 같은 것, 그러니까 단순 data 를 위한 class 를 위해서 class 를 만드는 것은 번거롭다. 그것을 간단하게 해준다. 아래처럼 data class 만 사용해서 parameter 를 적어주면 끝난다. 그럼알아서 property methods 등을 만들어준다.
data class Result(val result: Int, val status: Status)

Pair 

Pair 도 간단한 data class 로 되어 있다. Pair, Triple 을 이용해서 간략하게 dict 대신 사용할 수 있다.

doSomething(
  Pair(1, "test1"),
  Pair(2, "test2"),
)
fun doSomething(vararg values: Pair<Int, String>){
  for(v in values){
    val (num, val) = v
  }
}




Multi-declarations

data class 의 값을 개별 변수로 할당할 때 손쉽게 하는 방법이다.

data class Result(val result: Int, val status: Status)
fun function(...): Result {
// computations
return Result(result, status)
}
// Now, to use this function:
val (result, status) = function(...)



Parameter Class<T> class

보통 Class<T> type 의 parameter 인 경우 MyClass.class 이런식으로 parameter 를 넘겨준다. 이것을 kotlin 에서는 javaClass<MyClass> 이런 식으로 사용한다.
MyActivity.class --> javaClass<MyActivity>()


MyClass<T extends String>  --> Myclass<out T>
MyClass<T super String>  --> Myclass<in T>



object:

new 를 써서 anonymous function 을 만드는데, 이것을 kotlin 에서 object 라는 keyword 로 가능하게 해준다. object 를 만든다는 느낌으로 사용하면 될 것이다. 참고로 kotlin 에서 class 를 instantiate 하는데 new 를 사용하지 않는다.
toolbar.setNavigationOnClickListener(new View.OnClickListener(){
 public void onClick(View v){... }
})  

toolbar.setNavigationOnClickListener(object:View.OnClickListener {
                public override fun onClick(v:View) {...  }
            }
        )



local function, nested function


fun reachable(from: Vertex, to: Vertex): Boolean {
  val visited = HashSet<Vertex>()
  
  fun dfs(current: Vertex) {
    
    if (current == to){
      return@reachable true
    } 
    
    if (!visited.add(current)) 
      return
    
    for (v in current.neighbors)
      dfs(v)  // self-recursion
  }

  dfs(from)
  return false // if dfs() did not return true already
}


Regex


if(!Regex("\\d{8}").matches(getVal(viewId)))
    return "not match"    // return
return null




List

Idioms
val list = listOf("a", "b", "c")



Map

val map = mapOf("a" to 1, "b" to 2, "c" to 3)

println(map["key"])
map["key"] = value

for ((k, v) in map) {
    println("$k -> $v")
}



function pointer


fun mywork() = operation()
do(::mywork)
do(::operation) 
do({ operation() })

fun operation(){
    
}


val test: (a: String)-> Unit = {a->
    println(a)
    
}
fun main(args: Array<String>) {
    println("Hello, world!")
    
    test("dd")
    
    // assign
    val test2 = test
    test2("ddZ")
    println(test2)

    // use map
    val a = mapOf("func" to test)
    
    val test3 = a.get("func") ?: {a->}  // map return 값이 null 일 가능성이 있어서 ?: 이 필요하다.
    println(test3)
    test3("gggg")
    
}




상속, inheritance, constructor


//java
public class A extends B{
    private int a;
    public A(View v){
        super(v);
        a = v.getContext();
                
    }
}
// kotlin
class A(v: View) : B(v) {
    private val a: Int

    init {
        a = v.context.toInt()
    }
}



Extension





댓글 없음:

댓글 쓰기