The number of programming languages is bewildering. You may not know it, but there are more than 600 documented programming languages, and many more that aren’t. The common features of these programming languages are variables and functions. Variables and functions are, so to speak, the essence of programming languages. So in this section we will look at the use of variables and functions in Kotlin.

1. The variable

Let’s start with variables. The way Kotlin defines a variable is very different from the way Java defines a variable. In Java, if you want to define a variable, you need to declare the type of the variable before the variable. For example, int A indicates that A is an integer variable, and String B indicates that B is a String variable. Kotlin, on the other hand, allows only two keywords to be declared before a variable: val and var.

Val (short for value) is used to declare an immutable variable that can never be reassigned after initial assignment, corresponding to a final variable in Java.

Var (short for variable) is used to declare a mutable variable that can be reassigned after initial assignment, corresponding to non-final variables in Java.

If you have Java programming experience, you might wonder how the compiler knows what type a variable is if you just declare it with val or var. This is one of Kotlin’s unique features, as it has an excellent type derivation mechanism.

For example, in the kt file we created in the previous chapter, we wrote the following code:

fun main() {
    val a = 10
    println("a = " + a)
}
Copy the code

Note that Kotlin doesn’t use a semicolon at the end of each line of code, so if you’re used to Writing Java, this is a good place to start.

In the code above, we define a variable a using the val keyword and assign it a value of 10, where a is automatically derived as an integer. Because if you’re assigning an integer to A, then A has to be an integer, whereas if you’re assigning a string to A, then A is automatically derived as a string variable, which is Kotlin’s type inference mechanism.

Now we run the main() function, and the result, shown in Figure 1, is exactly what we expect.

However, Kotlin’s type inference mechanism does not always work. For example, if we assign a variable [1] late, Kotlin cannot automatically infer its type. To do this, you need to explicitly declare the variable type. Kotlin provides support for this functionality, with the syntax shown below:

[1] Variable delayed assignment: Immediate assignment is to calculate the expression on the right side of the equal sign and then assign it to the left side of the expression. Delayed assignment is to calculate the expression on the right side and call the variable on the left side in the subsequent code.

val a: Int = 10
Copy the code

As you can see, we explicitly declared the variable a to be of type Int, at which point Kotlin will no longer attempt type derivation. If you now try to assign a string to A, the compiler will throw a type mismatch exception.

If you studied Java and were careful enough, you might have noticed that Kotlin’s Int is capitalized, whereas Java’s Int is lowercase. Don’t overlook this one case difference; it means that Kotlin has completely abandoned the basic data types in Java and is using object data types entirely. Whereas in Java int is a keyword, in Kotlin int becomes a class with its own methods and inheritance structure. The following table lists the Kotlin object data types for each of the basic data types in Java.

Now, if we try to do some math on variable A, let’s say we make a 10 times bigger, you might naturally write something like this:

fun main() {
val a: Int = 10
a = a * 10
println("a = " + a)
}
Copy the code

Unfortunately, if you do this, the compiler will prompt an error: Val cannot be reassigned. This tells us that variables declared using the val keyword cannot be reassigned. The reason for this problem is that we initially assigned a to 10 and then made it 10 times larger on the next line, reassigning a and causing the compiler to report an error.

Solution to this problem is also very simple, as already mentioned, the val keyword used to declare an immutable variables, and the var keyword to declare a variable variables, so here you just need to change the val to the var, as shown below:

fun main() {
var a: Int = 10
a = a * 10
println("a = " + a)
}
Copy the code

Now that the compiler doesn’t report any more errors, rerun the code and the result should look like the following image.

You can see that the value of A has changed to 100, which means that our math operation worked.

Here you may be wondering: why use the val keyword when there are so many constraints? Just use the var keyword entirely. In fact, Kotlin designed this way to solve the problem that the final keyword in Java is not used properly.

In Java, a variable is mutable unless you actively declare the final keyword before it. This is not a good thing, however, as projects become more complex and more people work on them, you never know when and by whom a variable variable will be changed, even if it shouldn’t be, which often leads to problems that are difficult to detect. Therefore, it is a good programming practice to add the final keyword to a variable unless it is explicitly allowed to be modified.

However, not everyone can develop such good programming habits. I believe that at least 90 percent of Java programmers do not consciously prefix variables with the final keyword, simply because Java does not enforce it. Therefore, Kotlin designed it in a completely different way from Java, providing the keywords val and var, which must be declared mutable or immutable by the developer.

So when should we use val and when should we use var? The trick here is to always use val to declare a variable first, and then use var when val doesn’t meet your needs. The resulting program is more robust and conforms to high-quality coding specifications. Many people who are new to programming are confused about functions and methods and do not understand the difference between them. In fact, function and method are the same concept, these two names are translated from English, function is translated from function, method is translated from method, there is no difference between them, but different languages have different naming habits. And because the Java Chinese method is more commonly called, and the Kotlin function is more commonly called, this book will probably use the two names interchangeably, just know that they are the same thing and don’t confuse yourself there. A function is a vehicle for running code. You can write many lines of code in a function, and when you run the function, all the code in the function will run. The main() function we used earlier is a function, but it is special. It is the entry function of the program, that is, once the program runs, it starts from the main() function. But a program with only one main() function is obviously rudimentary. Like other programming languages, Kotlin allows us to define functions as we wish. The syntax is as follows:

2. The function

Many people who are new to programming are confused about functions and methods and do not understand the difference between them. In fact, function and method are the same concept, these two names are translated from English, function is translated from function, method is translated from method, there is no difference between them, but different languages have different naming habits. And because the Java Chinese method is more commonly called, and the Kotlin function is more commonly called, this book will probably use the two names interchangeably, just know that they are the same thing and don’t confuse yourself there.

A function is a vehicle for running code. You can write many lines of code in a function, and when you run the function, all the code in the function will run. The main() function we used earlier is a function, but it is special. It is the entry function of the program, that is, once the program runs, it starts from the main() function.

But a program with only one main() function is obviously rudimentary. Like other programming languages, Kotlin allows us to define functions as we wish. The syntax is as follows:

fun methodName(param1: Int, param2: Int): Int {
return 0
}
Copy the code

Fun (short for function) is the keyword that defines a function. Whenever you define a function, always use fun to declare it.

Following fun is the function name, which is not required. You can call it anything you like, but good programming practice dictates that the function name should have some meaning, some expression of what the function does.

The function name is followed by a pair of parentheses in which you can declare what arguments the function takes. The number of arguments can be any number, as in the example above, which means that the function takes two arguments of type Int. Parameters are declared in the format of “parameter name: parameter type”, where parameter names can also be defined arbitrarily, which is similar to function names. If you don’t want to receive any arguments, write a pair of empty parentheses.

The part after the argument parentheses is optional and is used to declare what type of data the function returns, as in the example above, the function returns an Int. If your function does not need to return any data, this section can be left blank. The last thing between the braces is the body of the function, where we can write the concrete logic of a function. Since the above example declares that the function returns an Int, we simply return a 0 in the function body.

This is the standard way to define a function, and while Kotlin has plenty of other functions that modify keywords, once you’ve mastered the function definition rules above, you should be able to handle more than 80% of programming scenarios. We’ll learn more about the other keywords later.

Let’s try to define a meaningful function using the same syntax as above, as follows:

    fun largerNumber(num1: Int, num2: Int): Int {
        return max(num1, num2)
}
Copy the code

Here we define a function called test(), which simply takes two integer arguments and always returns the larger of the two arguments.

Note that the above code uses a Max () function, a built-in function provided by Kotlin that returns the greater of the two arguments, so our test() function is essentially a wrapper around the Max () function.

Now you can implement the test() function in the LearnKotlin file. When you type the word “Max,” Android Studio will automatically pop up a code prompt like the one shown below.

Android Studio has very smart code prompts and completion features, and often you only need to type part of the code, and it automatically predicts what you want to write and gives you a list of prompts. We can move through the prompt list by pressing up and down, then press “Enter”, and Android Studio will automatically complete the code for us.

I highly recommend that you use The Code completion feature of Android Studio frequently. Some people may find it more satisfying to complete the code by hand, but I would like to remind you that Android Studio will not only complete the code for you, but also automatically guide the package, which is important. For example, the Max () function above, if you type all of it by hand, the function will prompt a red error, as shown below.

This error occurs because you did not import the Max () function package. Of course, there are several ways to guide a package. You can move your cursor over the red error to see a shortcut, but the best way to guide a package is to use Android Studio’s code completion feature, which automatically guides the package.

Now let’s write the Max () function again using code completion (Alt + Enter), and you’ll see that the LearnKotlin file’s header automatically imports a Max () package without any more errors, as shown in the figure below.

Now that the test() function is written, we can try calling it from the main() function and implement a simple function to find the larger of the two numbers, as follows:

fun main() {
        val a = 37
        val b = 43
        var value :Int
        value = test(a, b)
        println("larger number is " + value)
}

fun test(int1: Int,int2: Int): Int {
    return max(int1,int2)
}
Copy the code

This code is very simple. We define two variables a and b, a with the value 37 and B with the value 40, and then call test(), passing a and b as arguments. The test() function returns the larger of the two variables and finally prints out the return value. Now run the code and the result should look like the following figure. The program worked as we expected.

This is the most basic and common use of functions in Kotlin. Although the largerNumber() function we implemented here is simple, you can implement as complex a function as you want once you know the rules for defining functions.

3. Expand content

Let’s look at one more Kotlin function syntactic sugar, which will play a very important role in future development.

When there is only one line of code in a function, Kotlin allows us to write a single line of code at the end of the function definition without having to write the function body. For example, the test() function we just wrote had only one line of code, so we could simplify it to something like this:

fun main() {
        val a = 37
        val b = 43
        var value  = test(a, b)
        println("larger number is " + value)
}

// Notice that the function defined here has only 1 line
fun test(int1: Int,int2: Int): Int =  max(int1,int2)
Copy the code

With this syntax, the return keyword can also be omitted, and the equal sign is sufficient to express the meaning of the return value. Also, remember Kotlin’s excellent type derivation mechanism? Here, too, it can play an important role. Since Max () returns an Int, and we concatenate Max () with an equal sign at the end of the test() function, Kotlin can deduce that test() must also return an Int. Instead of explicitly declaring the return type, the code can be further simplified as follows:

fun test(int1: Int,int2: Int) =  max(int1,int2)
Copy the code

You might think that there are not many cases where a function is only one line of code, and this syntax isn’t very common. This is not the case, as it can also be used in conjunction with other Kotlin language features, which are helpful in simplifying code, but we’ll learn more about its usage scenarios later.