Kotlin Learn Notes (1) Basic Grammar

Keywords: Android Google Java Gradle

For Kotlin installation, Android studio 3.0 and above comes with it, others can be installed by searching for the plug-in Kotlin.Here's the syntax for Kotlin.

Here are my learning notes. Any inappropriate entry is welcome to make corrections.
Thank you ^^

1. Kotlin Android Extension

The Kotlin plug-in comes with an Android extension, so there is no need to install additional plug-ins separately.
We're prompted to configure Kotlin directly after the new Kotlin Activity

Automatically import the configuration Kotlin needs by clicking

There is actually one more line on the Gradle of the project

A lot more in the build.gradle of the project module

apply much more

These are all automatically generated

Then we need to add the following code to the build.gradle file of the project module

apply plugin: 'kotlin-android-extensions'

This allows us to use abbreviations, such as defining a TextView in XML

<TextView
        android:id="@+id/hello"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"/>

I set the ID here to "hello" and our code in the Activity becomes

class KotlinActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_kotlin)
        hello.text = "Are you silly?"
    }
}

This sets the content directly through hello.text instead of the long one

 findView(R.id.textView) as TextView

This plug-in is equivalent to using the control "id" in the XML as an extra property of the Activity.
A lot simpler ~~

2. Define Functions

All functions in Kotlin are declared directly through funs.

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

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

Both of the above can be called with the following code.

println(sum(3, 5))
// The output is as follows:
I/System.out: 8

3. Define local variables

val a: Int = 1  // Initialize Now
val b = 2   // Deduce Int Type
val c: Int  // Type must be declared when no initialization value is present
c = 3       // assignment
println("a = $a, b = $b, c = $c")
var x = 5 // Derive Int Type
x += 1
println(" x = $x")
// The output is as follows:
I/System.out: x = 6

4. Notes

Like Java and JavaScript, Kotlin supports single-line and block annotations.

5. Use string templates

var a = 1
// Use variable names as templates:
val s1 = "a is $a"
println(s1)

a = 2
// Use an expression as a template:
val s2 = "${s1.replace("is", "was")}, but now is $a"
println(s2)
println(s1)
// The output is as follows:
I/System.out: a is 1
I/System.out: a was 1, but now is 2                   
I/System.out: a is 1

I found that the value of s1 was modified by replace in val s2, but the value of s1 did not change when s1 was last output.
By entering the replac method, I know that the string will be regenerated after using this method, without changing the original value ~O() Ohaha~At first glance, I am not good at Java fundamentals~
Appendix:

6. Use conditional expressions

fun maxOf(a: Int, b: Int): Int {
    if (a > b) {
        return a
    } else {
        return b
    }
}
fun maxOf(a: Int, b: Int) = if (a > b) a else b
println("I am this year${maxOf(0, 18)}Age.")
hello.text = "I am this year${maxOf(0, 18)}Age."
//Output as follows:
I/System.out: I'm 18 years old.

Both of these can be expressed.

7. Use nullable variables and null value checks

The most common error in development should be NullPointerException, so how does Kotlin solve this problem?

7.1 Nullable and non-nullable types

Is it used in Kotlin to indicate whether the variable can be null or not.Here's an example


When we don't know that a String can be empty, an error will occur when a String is assigned null, causing it to fail.

The former can be called directly

val l2 = a2.length
 But the latter
val l3 = a3.length

We can't call it directly because a3 might be empty, so here we're going to use a conditional expression

7.2 Check null in condition

val l3 = if (a3 != null) a3.length else -1

// The output is as follows:
I/System.out: 3

perhaps

if (a3 != null && a3.isNotEmpty())
    println("Stirng of length ${a3.length}")
else
    println("Empty string")   
// The output is as follows:
I/System.out: Stirng of length 3

7.3 Security Calls

Use the security operator,?.

a3?.length

Returns the length if a3 is not empty, otherwise it is empty.
Is this expression of type Int?

Secure calls are useful in chain calls.For example, if Bob is an employee who may or may not assign a department, you can do this if you want to get Bob's department name as a prefix to his name:

bob?.department?.head?.name

Such a call chain returns NULL if either property is empty.

7.4 Elvis Operator

Using the Elvis operator,?:

val l = b.length?: -1

If?: The expression on the left is not empty, it returns, otherwise it returns the expression on the right.Note that the expression on the right will only return if the expression on the left is empty.

7.5!! Operator

With b!!, this returns a non-empty B or throws an NPE with B empty

val l = b !!.length

7.6 Security Conversion

A normal transformation may produce a ClassCastException exception.Another option is to use a secure conversion, which returns empty if unsuccessful:

var b = "aaa"
val aInt: Int? = b as? Int
println(aInt)
The output is as follows:
I/System.out: null

This way, if b is of type int, it will output instead of returning null
Instead of crash reporting ClassCastException exceptions as before

8. Use value checking and automatic conversion

Use the is operator to check whether an expression is an instance of a type.If you have type checked immutable local variables or attributes, there is no need to explicitly convert them:

fun printLength(obj: Any) {
    println("'$obj' string length is ${getStringLength(obj) ?: "... err, not a string"} ")
}
fun getStringLength(obj: Any): Int? {
  if (obj is String) {
    // obj will be automatically converted to String type in this branch
    return obj.length
  }

  // obj is still an Any type outside of the species check
  return null
}

By calling:

printLength("Incomprehensibilities")
printLength(1000)
printLength(listOf(Any()))
The output is as follows:
I/System.out: 'Incomprehensibilities' string length is 21 
I/System.out: '1000' string length is ... err, not a string 
I/System.out: '[java.lang.Object@72fd5e4]' string length is ... err, not a string 

Of course, we can also write in a different way

fun getStringLength(obj: Any): Int? {
  if (obj !is String) return null

  // obj will be automatically converted to String type in this branch
  return obj.length
}

Even so

fun getStringLength(obj: Any): Int? {
    // obj will be automatically converted to String type at &&right
  if (obj is String && obj.length > 0) {
    return obj.length
  }

  return null
}

The output of the above code is unchanged.

9. Use loops

val items = listOf("Google", "Apple", "Amazon")
for (index in items.indices) {
    println("item at $index is ${items[index]}")
}
// The output is as follows: 
I/System.out: item at 0 is Google
I/System.out: item at 1 is Apple
I/System.out: item at 2 is Amazon

10. Use a while loop

val items = listOf("Google", "Apple", "Amazon")
var index = 0
while (index < items.size) {
    println("item at $index is ${items[index]}")
    index++
}

The output is the same as the for loop

11. Use when expressions

The when expression in Kotlin is similar to a switch statement in Java

when (obj) {
  1          -> "One"
  "Hello"    -> "Greeting"
  is Long    -> "Long"
  !is String -> "Not a string"
  else       -> "Unknown"
}
println(describe(1))
println(describe("Hello"))
println(describe(1000L))
println(describe(2))
println(describe("other"))

The parameters are used as "1", "Hello", "1000L", "2", "other".
The following outputs correspond to each other.Just like switch syntax, it simplifies some processes.

// The output is as follows:
I/System.out: item at 2 is kiwi
I/System.out: One
I/System.out: Greeting
I/System.out: Long
I/System.out: Not a string
I/System.out: Unknown

May be confused about the fourth

println(describe(2))

!is String -> "Not a string"

This means that 2 is not an instance of String type, and the result is true so'Not a string'is output

12. Use ranges

Use the in operator to check if the value is in a range:

val x = 10
val y = 9
if (x in 1..y+1) {
    println("fits in range")
}
// The output is as follows:
I/System.out: fits in range

Expression means whether x is in the range of 1 ~ y + 1
From the defined values of x and y, this is clearly true

Check if the value is outside the range:

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

if (-1 !in 0..list.lastIndex) {
    println("list.lastIndex: ${list.lastIndex}")
    println("-1 is out of range")
}

if (list.size !in list.indices) {
    println("list.indices: ${list.indices}")
    println("list size is out of valid list indices range too")
}
// The output is as follows:
I/System.out: list.lastIndex: 2
I/System.out: -1 is out of range
I/System.out: list.indices: 0..2
I/System.out: list size is out of valid list indices range too

! in does not belong to this range - 1 does not belong to 0~2, 3 does not belong to 0~2
So their println statements are all output.

Iterate within a range or use steps:

for (x in 1..5) {
  println(x)
}

println("----------------")

for (x in 1..10 step 2) {
  println(x)
}

println("----------------")

for (x in 9 downTo 0 step 3) {
  println(x)
}
// The output is as follows:
I/System.out: 1
I/System.out: 2
I/System.out: 3
I/System.out: 4
I/System.out: 5
I/System.out: ----------------
I/System.out: 1
I/System.out: 3
I/System.out: 5
I/System.out: 7
I/System.out: 9
I/System.out: ----------------
I/System.out: 9
I/System.out: 6
I/System.out: 3
I/System.out: 0

step Jump
downTo from large to small
Looking at the Log log, smart you should understand ~~

13. Using collections

Iterate over a set:

val items = listOf("Google", "Apple", "Amazon")
for (item in items) {
    println(item)
}

println("----------------")

when {
       "tutu_oo" in items -> println("Change The World")
       "Google" in items -> println("My Dream")
}        

println("----------------")

val fruits = listOf("banana", "avocado", "apple", "kiwi")
   fruits
           .filter { it.startsWith("a") }
           .sortedBy { it }
           .map { it.toUpperCase() }
           .forEach { println(it) }
I/System.out: Google
I/System.out: Apple
I/System.out: Amazon
I/System.out: ----------------
I/System.out: My Dream
I/System.out: ----------------
I/System.out: APPLE
I/System.out: AVOCADO
I/System.out: ----------------

The first is the most common circular printing
Next comes the when expression, which executes only once
If the expression is like this

when {
       "Amazon" in items -> println("Change The World")
       "Google" in items -> println("My Dream")
} 
I/System.out: Google
I/System.out: Apple
I/System.out: Amazon
I/System.out: ----------------
I/System.out: Change The World
I/System.out: ----------------
I/System.out: APPLE
I/System.out: AVOCADO
I/System.out: ----------------

The latter Google will not output My Dream even if it is in the items collection

Finally, the chain call reminds me of RxJava, which first filter s to leave only the beginning of `a', then should be a natural sort, then map s to uppercase, and finally outputs each.

About me

A growing picture.

Thank

Reference from:
https://www.kotlincn.net/docs/tutorials/android-plugin.html

https://huanglizhuo.gitbooks.io/kotlin-in-chinese/content/GettingStarted/Basic-Syntax.html

Posted by Lee on Mon, 24 Jun 2019 09:46:41 -0700