Kotlin basic grammar study
Simple entry into a door, complex operations in the next section
Kotlin package
- Unlike Java packages, kotlin packages do not require Java classes to be placed in the same directory as the package name
- Kotlin class names can also be different from file names
- Kotlin doesn’t even have to write classes
package base
fun funcMax(a: Int, b: Int): Int {
return if(a > b) a else b
}
fun main(args: Array<String>) {
var a = 10
var b = 20
println(funcMax(a, b))
}
Copy the code
Learned Java with the source code to see
public final class FuncDemo01Kt {
public static final int funcMax(int a, int b) {
return a > b ? a : b;
}
public static final void main(@NotNull String[] args) {
int a = 10;
int b = 20;
intvar3 = funcMax(a, b); System.out.println(var3); }}Copy the code
You can see it here
The Kotlin compiler makes the file FuncDemo01 + Kt a Java class name, while Max is a static method, called a top-level function in Kotlin
So if you call a Kotlin method in a Java class without a class name, consider using the class name. Static functions (funcdemo01kt. funcMax) are used in this way
Here’s how Java calls kotlin’s methods
package base.java;
import base.FuncDemo01Kt;
public class JavaTestDemo01 {
public static void main(String[] args) throws Exception {
int a = 10;
int b = 30; System.out.println(FuncDemo01Kt.funcMax(a, b)); }}Copy the code
Function declaration and definition
The kotlin function definition is done using the fun keyword:
- Function body form
fun sum(a: Int, b: Int):Int {
return a + b
}
Copy the code
Fun keyword + space + function name (parameter name: parameter type,...) Function return value {function body}
- Expression in the body of a function
fun sum(a: Int, b: Int) = a + b
Copy the code
Fun keyword + space + function name (parameter name: parameter type,...) Expression function body (= a + b)
// Kotlin uses the 'Unit' keyword when the function returns no value. Note the distinction between 'Uint' and 'unsigned int', meaning 'unsigned int'
fun sum(a: Int, b: Int):Unit {
// String template operation keyword '$'
println("max = ${if(a > b) a else b}")}Copy the code
Statements are usually wrapped around a block of code. In Kotlin, an if statement is an expression. It has a return value, such as: Val Max = if(a > b) a else b But in Kotlin, assignment is a statement, so it can’t
- What is the expression function body
If the whole body of a function is an expression, we can call it an expression body
fun max(a: Int, b: Int) = if (a > b) a else b
Copy the code
Where = if(a > b) a else b is the expression function body
In the body of an expression function, we can omit the return keyword, as in the if expression above
- Variable function parameter
fun printArray(vararg arr: Int) {
for(v in arr) {
println(v)
}
}
Copy the code
- Lambda and anonymous functions
- Anonymous functions
A non-anonymous function looks like this:
fun max(x: Int, y: Int): Int {
return x + y
}
Copy the code
Derive anonymous functions: If you remove the name of a named function, it is an anonymous function. However, if you remove the name, the anonymous function cannot be used by programmers, so you usually need to define a variable or function type parameter to receive it
// The following code is incorrect, there is no way to use the anonymous function
fun (x: Int, y: Int): Int {
return x + y
}
Copy the code
// The following f is the function type variable
val f = fun (x: Int, y: Int): Int {
return x + y
}
// Now we can use the function with the f variable
val sum = f(190.29)
Copy the code
We can also use:
fun running(x: Int, y: Int, funType: (Int.Int) - >Int): Int {
return funcType(x, y)
}
// Call the method
running(10.299.fun (x, y): Int {
return x + y
})
// lambda expressions
running(10.299, { x, y -> x + y })
// lambda expressions
running(10.299) { x, y ->
// Write multiple lines of code in the lambda expression
val ret = x + y
println("ret = $ret")
ret
}
Copy the code
Remember: an anonymous function is an object, an object that comes out of a function type new, and a function type is just a type, like Int Double Float String Byte Long and so on, it’s not an object, it’s not an object, it’s not an object, it’s not an object, that’s really useful
- Lambda expressions
In Kotlin, any expression wrapped in {} that uses -> split arguments and function bodies is called a lambda expression, for example: {x, y -> if (x > y) x else y}
// lambda expressions
val x: (Int.Int) - >Int = { x, y -> if (x > y) x else y }
// Anonymous function mode
val y: (Int.Int) - >Int = fun(x: Int, y: Int): Int {
return if (x > y) x else y
}
Copy the code
(Int, Int) -> Int is a function type, but remember it’s not an object it’s not an object it’s not an object it’s not an object, it’s a type
Var f = (Int, Int) -> Int
Var f: (Int, Int) -> Int; var f: (Int, Int) -> Int
// Kotlin initializes the f type using lambda expressions
fun f: (Int.Int) -> Int = { x, y -> x + y }
Copy the code
fun max(x: Int, y: Int): Int {
return if(x > y) x else y
}
Copy the code
fun sum2(x: Int, y: Int) = x + y
Copy the code
The above two functions have the same return value and parameter type except the function name and function body, and can be directly assigned to the corresponding parameter
The function down here doesn’t work
fun printXY(x: Int, y: Int) = println("x = $x, y = $y")
Copy the code
Its return value is Unit, that is, there is no return value, and (Int, Int) -> Int does not match
// The return value will no longer be an Int
fun sum1(x: Int, y: Int) = {x: Int, y: Int -> x + y}
Copy the code
Fun sum1(x: Int, y: Int) = {x, y -> x + y}
The type of this parameter cannot be inferred. Please specify clearly.
And then I manually added an Int to x and y, but I wonder why? Lambda expression object = to the function. I don’t really know what the = compiler on this function is doing with it, right?
fun sum1(x: Int, y: Int) = {x: Int, y: Int – > x + y} it actually can also be written, but the return value will no longer be the result of x + y type Int, is (Int, Int) – > Int, this way, only shows that we forgot, lambda expressions is also an object, an anonymous function object. And it’s not clear what theta does on the function?
Fun sum1(x: Int, y: Int) = {x: Int, y: Int -> x + y} Why take that extra step? So, the return type changes, of course you can use it that way, but this is just saying what does theta do on the function?
// Use lambda to solve the problem. Emmm
fun sum1(x: Int, y: Int) = {x: Int, y: Int -> x + y}.invoke(x, y)
Copy the code
Fun sum(x: Int, y: Int) = x + y
But it’s important to note that this x+y form is not a lambda anymore. Remember what I said at the beginning? {argument -> function body} this is a lambda expression
The invoke function?
val f = {x, y -> x + y}
// Invoke is also called.
val ret = f.invoke(x, y)
println(ret)
Copy the code
F above is also of type (Int, Int) -> Int
Fun sum(x: Int, y: fun sum(x: Int, y: fun sum(x: Int, y: fun sum(x: Int, y: fun sum(x: Int, y: fun sum)) Int: (Int, Int) -> Int = {x: Int, y: Int -> x + y} why is his return type (Int, Int) -> Int
val f: (Int.Int) - >Int = {x, y -> x + y}
fun sun3(x: Int, y: Int): (Int.Int) - >Int = f
// What is the difference between the top and bottom?
fun sum4(x: Int, y: Int): Double = 3.14159265
Copy the code
Is it something like:
val f: (Int.Int) - >Int = {x, y -> x + y}
fun sum3(x: Int, y: Int): (Int.Int) - >Int {
return f
}
val d: Double = 3.141592653
fun sum4(x: Int, y: Int): Double {
return d
}
Copy the code
Do you understand now?
Fun sum4(x: Int, y: Int): Once the = in Double = 3.14159265 is recognized by the compiler, it puts the 3.14159265 object inside a {} and prefaces the object with a return
Such as:
fun sum5(x: Int, y: Int): Unit = println("x + y = ${x + y}")
Copy the code
If I do it the way I did it
fun sum5(x: Int, y: Int): Unit {
return println("x + y = ${x + y}")}Copy the code
Nothing wrong with it?? In the same way
fun sum1(x: Int, y: Int): (Int.Int) - >Int {
return {x: Int, y: Int -> x + y}
}
Copy the code
Reminds me of a teacher who told me to learn a programming language from the perspective of a compiler…
variable
Val /var Variable name: the type of the variable
Val is similar to a final variable in Java, and var is a non-final variable that references an immutable variable
When val v: Int is declared, the variable v needs to be initialized later if it is not initialized
// If it is a declaration, you need to determine the type
val v: Int
v = 10
Copy the code
Var defines a variable whose type, once initialized, remains the same the next time it is assigned
var v = 10
v = "hello" // error, v is already an Int, cannot be changed to a String
Copy the code
String formatting template
fun main(args: Array<String>) {
var a: Int = 99;
var b = 11; // The type is derived to Int
println("a = $a, b = $b, a + b = ${a + b}")}Copy the code
The above code is how the Kotlin string template is used
The $variable
Print the value of the variable directly${expression}
Expressions can be written inside curly braces
When decompiled into Java code, the string manipulation template above becomes
public final class StringDemo01Kt {
public static final void main(@NotNull String[] args) {
Intrinsics.checkNotNullParameter(args, "args");
int a = 99;
int b = 11;
String var3 = "a = " + a + ", b = " + b + ", a + b = "+ (a + b); System.out.println(var3); }}Copy the code
Watch window: String var3 = “a =” + a + “, b = “+ b +”, a + b = “+ (a + b);
Classes and properties
- class
In Java classes are written like this:
public class Person {
private String name;
private int age;
public final String getName(a) {
return this.name;
}
public final void setName(String name) {
this.name = name;
}
public final int getAge(a) {
return this.age;
}
public final void setAge(int age) {
this.age = age;
}
public Person(String name, int age) {
this.name = name;
this.age = age; }}Copy the code
Using IDEA Java to Kotlin code converter converted into Kotlin source code after:
class Person(var name: String, var age: Int)
Copy the code
It looks much more comfortable
When Java is converted to Kotlin, public is hidden. In Kotlin, the class is public by default, while in Java, it is default (public Default protected private).
Class Person(var name: String, var age: String) class Person(var name: String, var age: String) Int) and the function argument doesn’t need val/var fun sum(a: Int, b: Int) probably because it doesn’t use get/set. Vararg
(vararg arr: String)
- attribute
- The difference between attributes and fields
① In Java: private String name; Get /set = get/set = get/set = get/set = get/set SetProperty (XXX) {this.setProperty(XXX) {this.setProperty(XXX) {this.setProperty(XXX) {this.setProperty(XXX)}} This.property calls this.getProperty() in Java.
(2) in kotlin val/var statement variables, if the val, define a variable will be marked as read-only property, only generates the get method, generating set method, if use var to define variables and generate a set/get methods
When the kotlin attribute var isDelete is encountered, kotlin generates the isDelete and setDeelte methods, with is replaced by set
- Custom property accessors
class Rectangle(val hight: Int.val width: Int) {
val isSquare: Boolean
// get() {
// return hight == width
//} // normal function body form
// get() {hight == width} // lamdba form
get() = hight == width // The expression function body
}
Copy the code
- In the kotlin
import
The keyword
In Kotlin, you can import classes and top-level functions (called static functions in Java).
Write an extension function in Kotlin (the one that passes this as an argument)
fun String.lasts(a): Char = this[this.length - 1]
Copy the code
If you use the extension function in kotlin, val ch = “kotlin”.lasts()
In Java, it is written like this:
// The core code here passes the call lasts object as an argument, which is done by the Kotlin virtual machine
public static final Char lasts(String /* This is the object on which this method is called, as in the previous example "kotlin" */ this) {
// "kotlin".charat ("kotlin".length() -1) looks like this
return this.charAt(this.length() - 1);
}
Copy the code
Come up with some of the following points, and then you can come back to it
If we call the lasts top-level function in another package, we’ll see it above Kotlin
import base.func.lastChar
Copy the code
The previous base.func is the package name, while lastChar is the method
If you want to call it in Java from another package, it becomes
import base.func.ExtensionFuncKt;
public class ExtensionDemo01 {
public static void main(String[] args) {
System.out.println(ExtensionFuncKt.lastChar("zhazha")); }}Copy the code
Enumeration class
enum class Color(val r: Int.val g: Int.val b: Int) {
RED(255.0.0), ORANGE(255.165.0), YELLOW(255.255.0), GREEN(0.255.0), BLUE(
0.0.255
),
INDIGO(75.0.130), VIOLET(238.130.238);
fun rgb(a) = (r * 256 + g) * 256 + b
fun getWarmth(a) = when (this) {
RED, ORANGE, YELLOW -> "warm"
GREEN -> "neutral"
BLUE, INDIGO, VIOLET -> "cold"}}Copy the code
Use enumeration classes to learn how to use when expressions
When the expression
(1) Use the form of function expression body
fun getWarmth(a) = when (this) {
RED, ORANGE, YELLOW -> "warm"
GREEN -> "neutral"
BLUE, INDIGO, VIOLET -> "cold"
}
Copy the code
(2) Function body form
fun getWarmth1(a): String {
when (this) {
RED, ORANGE, YELLOW -> return "warm"
GREEN -> return "neutral"
BLUE, INDIGO, VIOLET -> return "cold"}}Copy the code
Intelligent type conversion and IS expression type conversion
interface Expr {}class Num(val value: Int): Expr
class Sum(val left: Expr, val right: Expr): Expr
fun eval(e: Expr): Int {
if (e is Num) {
return e.value
}
else if (e is Sum) {
return eval(e.left) + eval(e.right)
}
throw IllegalArgumentException("Unknown expression")}fun main(a) {
println(eval(Sum(Num(1), Sum(Num(2), Num(3)))))}Copy the code
If (e is Num) if the judgment returns true, then the variable e is intelligently converted to Num
However, there is a precondition for using the IS expression: the variable must be a variable defined by val; otherwise, there is no intelligent conversion, and only the conversion shown by the AS expression can be used
println((sum.left as Num).value)
val n = e as Num
Copy the code
We can also use when instead of if expressions
Intervals, sequences and loops
- interval
There’s no regular for loop in Kotlin for(int I = 0; i < length; I++), so introducing intervals is a better substitute for this operation
1.. 10 interval expression, representing the number between [1, 10], including 1 and 10
fun main(a) {
val interval: IntRange = 1.10.
for (v in interval) {
print("$v ")
}
println()
for (v in interval.last downTo interval.first step 1) {
print("$v ")
}
println()
/ / [1, 10)
for (v in interval.first until interval.last) {
print("$v ")}}Copy the code
1 2 3 4 5 6 7 8 9 10
10 9 8 7 6 5 4 3 2 1
1 2 3 4 5 6 7 8 9
Copy the code
- Iterative map
fun main(a) {
val map = mutableMapOf(
1 to "zhazha".2 to "haha".3 to "haha",
Pair(4."xixi"),
Pair<Int, String>(5."heihei")
)
map.forEach(fun(m: Map.Entry<Int, String>): Unit {
println("key = ${m.key}, value = ${m.value}")})for ((key, value) in map) {
println("key = $key, value = $value")}// java forEach??? Call the BiConsumer interface in the Java Map
map.forEach { key, value ->
println("key = $key, value = $value")}// Kotlin forEach??? Call kotlin's (key, value) -> {} to traverse the Map method
map.forEach { (key, value) ->
println("key = $key, value = $value")}}Copy the code
fun Set<String>.inSet(str: String) = str in this
val set = setOf<String>("1"."2"."3"."4"."a"."b"."c")
println(set.inSet("a"))
// (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')
fun isLetter(ch: Char) = ch in 'a'.'z' || ch in 'A'.'Z'
// ch >= '0' && ch <= '9'
fun inNumber(ch: Char) = ch in '0'.'9'
Copy the code
Kotlin abnormal
In Kotlin, exceptions may or may not be handled. They are not on the function declaration, throw new Exception(” XXXX “) is not required.
fun main(a) {
val bufferedReader = BufferedReader(InputStreamReader(System.`in`))
val number = readNumber(bufferedReader)
println(number)
}
fun readNumber(reader: BufferedReader): Int? = try {
val line = reader.readLine()
Integer.parseInt(line)
} catch (e: NumberFormatException) {
throw e
} finally {
reader.close()
}
Copy the code