Skip to content

Latest commit

 

History

History
257 lines (163 loc) · 6.02 KB

README_Syntax.md

File metadata and controls

257 lines (163 loc) · 6.02 KB

Function declaration:

fun methodName(params:paramType): ReturnType {
	// fun body
}

example:

fun sum(a: Int, b: Int): Int {
		return a + b
}

if there is just one line for fun body, we can say (Single-Expression functions):

fun sum(a: Int, b: Int) = a + b

Unit return type can be omitted: // Unit equals void, no return value;

fun printSum(a: Int, b: Int): Unit {
		println("sum of $a and $b is ${a + b}")
}

we can assign the default value for params, like:

fun foo(a: Int = 0, b: String = "") { ... }

we can use vararg to indicate Variable number of arguments.

Generic Functions: fun singletonList(item: T): List { ... }

Extension Functions: we can use Extension Funcs to extend the method in the original class.

fun ClassType.functionName(parmas:pramaType): ReturnType {
	// func body
}

for example. we can extend String class with firstAndLast() func. Extensions are resolved statically.

Anonymous function: lambda anonymous function can be used for the params of other function or return vlaue of other function.

{ params:paramsType -> func body }

for example: { x:Int, y:Int -> x + y }

we can also assign Anonymous function to one variable like:

var sum = { x:Int, y:Int -> x + y }
println(sum(2, 3))

sum just points to the funtion.

Higher-Order Functions:

function type declaration:

(paramsType) -> ReturnType

for example:   (Int, Int) -> Int

higher order function example:

fun compute(a:Int, b:Int, c:(Int, Int) -> Int):Int = c(a,b)

Inline Functions:

Defining variables: val: read-only, equals to "final" in Java var: variable

var <variableName>:<variableType> = <initial value>

var <variableName>:<variableType> = <intial value>

example:

val a: Int = 1  // immediate assignment
val b = 2       // `Int` type is inferred
val c: Int      // Type required when no initializer is provided
c = 3           // deferred assignment

var x = 5       // `Int` type is inferred
x += 1

Using nullable values and checking for null: ? A reference must be explicitly marked as nullable when null value is possible.

example:

var b: String? = "abc"
b = null // ok
print(b)

var a: String = "abc"
a = null // compilation error sine a is defined as NonNull able variable


// check if variable is null or not
var strNull:String? = "Kotlin"
if (strNull == null) {
		println("null");
} esle {
		println(strNull.length)
}

we can say as below: var strNull:String? = "Kotlin" println(strNull?.length)

we can also use let funcation and lambda to execute: var strNull:String? = "Kotlin" strNull?.let({println(it)}) // check let function

Elvis Operator: ?:

return a ?: b

when a is non-null, return a; otherwise, return b;

The is Operator: (equals to isInstance in Java)

The !! Operator: the not-null assertion operator (!!) converts any value to a non-null type and throws an exception if the value is null.

example:
	val l = b!!.length

if b is not null, return a non-null value of b; or throw an NPE if b is null.

Safe Cast: as? make sure the type compatible. Otherwise, it's better to use is check type in advance.

val aInt: Int? = a as? Int

Loop: val items = listOf("apple", "banana", "kiwifruit") for (item in items) { println(item) }

When experssion: (equals to switch)

when (variable) {
		case1 -> { body 1 } or value
		case2 -> { body 2 } or value
		...
		else -> { body unknown} or value
}

Using the range: val x = 10 val y = 9 if (x in 1..y+1) { println("fits in range") }

@Lable: Any expression in Kotlin may be marked with a label. Labels have the form of an identifier followed by the @ sign, for example: abc@.

loop@ for (i in 1..100) {
	for (j in 1..100) {
    	if (...) break@loop
	}
}

Return at Labels:

Class:

constructor exmaple: pirmary constructor A class in Kotlin can have a primary constructor and one or more secondary constructors. The primary constructor is part of the class header: it goes after the class name (and optional type parameters).

class Person <constructor>(firstName: String) { ... }

The primary constructor cannot contain any code. Initialization code can be placed in initializer blocks, which are prefixed with the init keyword.

for declaring properties and initializing them from the primary constructor:

class Person(val firstName: String, val lastName: String, var age: Int) { ... }

The class can also declare secondary constructors, which are prefixed with constructor:

class Person {
		var children: MutableList<Person> = mutableListOf<Person>();
		constructor(parent: Person) {
    		parent.children.add(this)
		}
}

secondary MUST delegate to the primary constructor. like constructor() : this()

creat a class instance:
	val customer = Customer("Joe Smith")

Inside an inner class, accessing the superclass of the outer class is done with the super keyword qualified with the outer class name: super@Outer.

Kotlin has no static method, we can define Companion Objects to access the class' member or method. Or we can use package top-level method to do that.

Properties and Fields:

The full syntax for declaring a property is

var <propertyName>[: <PropertyType>] [= <property_initializer>]
	[<getter>]
	[<setter>]

Late-Initialized Properties and Variables: lateinit keyword

Delegated Properties: by keyword var m:String by Test()

class Test() { //common logic }

Extensions: provides the ability to extend a class with new functionality without having to inherit from the class or use any type of design pattern such as Decorator.

if extenstion function has the same name with member function, member func always wins.

Data Classes: data class User(val name: String, val age: Int)

Destructuring Declarations: val (name, age) = person

Sealed Classes: useful to deal with when experssion, don't need to cover else since sealed class already covers all caese.

Anonymous inner classes: Anonymous inner class instances are created using an object expression. functional Java interface (i.e. a Java interface with a single abstract method), using lambda instead.