Kotlin essay 2019-10-31
1.Hello world
fun main(){
println("hello world")
}
Notice
If you don’t specify a package in a source file, its content goes to the default package. In Kotlin versions earlier than 1.3, the main function must have a parameter of type Array<String>.
fun main(args: Array<String>) {
println("Hello, World!")
}
2.Functions
//function type 1
fun printMessage(message: String): Unit {
println(message)
}
//function type 2
fun printMessageWithPrefix(message: String, prefix: String = "Info") {
println("[$prefix] $message")
}
//function type 3
fun sum(x: Int, y: Int): Int {
return x + y
}
//function type 4
fun multiply(x: Int, y: Int) = x * y
fun main() {
printMessage("Hello")
printMessageWithPrefix("Hello", "Log")
printMessageWithPrefix("Hello")
printMessageWithPrefix(prefix = "Log", message = "Hello")
println(sum(1, 2))
}
result:
Hello
[Log] Hello
[Info] Hello
[Log] Hello
3
Notice
Default return type is Unit,it can be omitted.
Infix Functions
fun main() {
infix fun Int.times(str: String) = str.repeat(this) // 1
println(2 times "Bye ") // 2
val pair = "Ferrari" to "Katrina" // 3
println(pair)
infix fun String.onto(other: String) = Pair(this, other) // 4
val myPair = "McLaren" onto "Lucas"
println(myPair)
val sophia = Person("Sophia")
val claudia = Person("Claudia")
sophia likes claudia // 5
}
class Person(val name: String) {
val likedPeople = mutableListOf<Person>()
infix fun likes(other: Person) { likedPeople.add(other) } // 6
}
result:
Bye Bye
(Ferrari, Katrina)
(McLaren, Lucas)
Operator Functions
fun main() {
operator fun Int.times(str: String) = str.repeat(this) // 1
println(2 * "Bye ") // 2
operator fun String.get(range: IntRange) = substring(range) // 3
val str = "Always forgive your enemies; nothing annoys them so much."
println(str[0..14]) // 4
}
result:
Bye Bye
Always forgive
Functions with vararg Parameters
Varargs allow you to pass any number of arguments by separating them with commas.
fun printAll(vararg messages: String) { // 1
for (m in messages) println(m)
}
printAll("Hello", "Hallo", "Salut", "Hola", "你好") // 2
fun printAllWithPrefix(vararg messages: String, prefix: String) { // 3
for (m in messages) println(prefix + m)
}
printAllWithPrefix(
"Hello", "Hallo", "Salut", "Hola", "你好",
prefix = "Greeting: " // 4
)
fun log(vararg entries: String) {
printAll(*entries) // 5
}
result:
Hello
Hallo
Salut
Hola
你好
Greeting: Hello
Greeting: Hallo
Greeting: Salut
Greeting: Hola
Greeting: 你好
3. Variables
Kotlin has powerful type inference. Kotlin does not enforce immutability. Use val over var.
fun main() {
var a: String = "initial" // 1
println(a)
val b: Int = 1 // 2
val c = 3 // 3
println(b)
println(c)
}
result:
initial
1
3
Notice
You’re free to choose when you initialize a variable, however, it must be initialized before the first read. e.g.1:
fun main() {
var e: Int // 1
println(e) // 2
}
result:
Variable 'e' must be initialized
e.g.2:
fun someCondition() = true
fun main() {
val d: Int // 1
if (someCondition()) {
d = 1 // 2
} else {
d = 2 // 2
}
println(d) // 3
}
result:
1
4. Null Safety
In an effort to rid the world of NullPointerException, variable types in Kotlin don’t allow the assignment of null. If you need a variable that can be null, declare it nullable by adding ? at the end of its type.
fun main() {
var neverNull: String = "This can't be null" // 1
neverNull = null // 2 error
var nullable: String? = "You can keep a null here" // 3
nullable = null // 4
var inferredNonNull = "The compiler assumes non-null" // 5
inferredNonNull = null // 6 error
fun strLength(notNull: String): Int { // 7
return notNull.length
}
strLength(neverNull) // 8
strLength(nullable) // 9 error
}
result:
Null can not be a value of a non-null type String
Null can not be a value of a non-null type String
Type mismatch: inferred type is String? but String was expected
5. Classes
Class name,class header and class body. if the class has no body, curly braces can be omitted.
class Customer // 1
class Contact(val id: Int, var email: String) // 2
fun main() {
val customer = Customer() // 3
val contact = Contact(1, "mary@gmail.com") // 4
println(contact.id) // 5
contact.email = "jane@gmail.com" // 6
println(contact.email) // 7
}
result:
1
jane@gmail.com
6. Generics
Generic Classes
class MutableStack<E>(vararg items: E) { // 1
private val elements = items.toMutableList()
fun push(element: E) = elements.add(element) // 2
fun peek(): E = elements.last() // 3
fun pop(): E = elements.removeAt(elements.size - 1)
fun isEmpty() = elements.isEmpty()
fun size() = elements.size
override fun toString() = "MutableStack(${elements.joinToString()})"
}
fun main() {
val stack = MutableStack(0.62, 3.14, 2.7)
stack.push(9.87)
println(stack)
println("peek(): ${stack.peek()}")
println(stack)
for (i in 1..stack.size()) {
println("pop(): ${stack.pop()}")
println(stack)
}
}
result:
MutableStack(0.62, 3.14, 2.7, 9.87)
peek(): 9.87
MutableStack(0.62, 3.14, 2.7, 9.87)
pop(): 9.87
MutableStack(0.62, 3.14, 2.7)
pop(): 2.7
MutableStack(0.62, 3.14)
pop(): 3.14
MutableStack(0.62)
pop(): 0.62
MutableStack()
Generic Functions
class MutableStack<E>(vararg items: E) { // 1
private val elements = items.toMutableList()
fun push(element: E) = elements.add(element) // 2
fun peek(): E = elements.last() // 3
fun pop(): E = elements.removeAt(elements.size - 1)
fun isEmpty() = elements.isEmpty()
fun size() = elements.size
override fun toString() = "MutableStack(${elements.joinToString()})"
}
fun <E> mutableStackOf(vararg elements: E) = MutableStack(*elements)
fun main() {
val stack = mutableStackOf(0.62, 3.14, 2.7)
println(stack)
}
result:
MutableStack(0.62, 3.14, 2.7)
7. Inheritance
open class Dog { // 1
open fun sayHello() { // 2
println("wow wow!")
}
}
class Yorkshire : Dog() { // 3
override fun sayHello() { // 4
println("wif wif!")
}
}
fun main() {
val dog: Dog = Yorkshire()
dog.sayHello()
}
result:
wif wif!
Notice
Kotlin classes are final by default. Kotlin methods are also final by default.
Inheritance with Parameterized Constructor
open class Tiger(val origin: String) {
fun sayHello() {
println("A tiger from $origin says: grrhhh!")
}
}
class SiberianTiger : Tiger("Siberia") // 1
fun main() {
val tiger: Tiger = SiberianTiger()
tiger.sayHello()
}
result:
A tiger from Siberia says: grrhhh!
Passing Constructor Arguments to Superclass
open class Lion(val name: String, val origin: String) {
fun sayHello() {
println("$name, the lion from $origin says: graoh!")
}
}
class Asiatic(name: String) : Lion(name = name, origin = "India") // 1
fun main() {
val lion: Lion = Asiatic("Rufo") // 2
lion.sayHello()
}
result:
Rufo, the lion from India says: graoh!
Asiatic name pass to Lion name.