KOTLIN development language documentation (official documentation), kotlin development language
Web link: https://kotlinlang.org/docs/reference/basic-types.html
2. Basic Concepts 2.1. Basic Types
From the perspective of Calling member functions and attributes in any variable processing, everything in the Kotlin development language is an object. Some types are embedded, and their implementations are optimized. What you see is still the original class. In this section, we illustrate most of these types: Numbers, characters, Boolean and array.
2.1.1. Number
The Kotlin development language processes arrays in a way similar to the Java development language, but there are also differences. For example, there is no implicit number widening conversion, and in the same case, the text is somewhat different.
The Kotlin development language provides the following built-in types of numbers (similar to the Java development language ):
Type |
Bit Width |
Double |
64 |
Float |
32 |
Long |
64 |
Int |
32 |
Short |
16 |
Byte |
8 |
Note: In the Kotlin development language, characters do not belong to arrays.
2.1.1.1. Text constant
There are several literal constants for integer values:
-- Decimal: 123
-- Additional capital letter L standard long integer: 123L
-- Hexadecimal number: 0x0F
-- Binary: 0b00001011
Note: Octal numbers are not supported.
The Kotlin development language also supports General floating-point representation:
-- The default value is dual precision: 123.5, 123.5e10.
-- Add f or F to indicate a single-precision floating point number: 123.5F
2.1.1.2. Representation
On the Java development language platform, numbers exist physically as the basic JVM type, unless a null numeric reference (such as: Int?) is required ?) Or include it in the generic type. In the latter case, the number is boxed.
Note that the number packing is inconsistent:
1 val a: Int = 100002 print (a = a) // print 'true' 3 val boxedA: Int? = A4 val anotherBoxedA: Int? = A5 print (boxedA === anotherBoxedA )//!!! Print 'false '!!!
On the other hand, it remains equal:
1 val a: Int = 100002 print (a = a) // print 'true' 3 val boxedA: Int? = A4 val anotherBoxedA: Int? = A5 print (boxedA = anotherBoxedA) // print 'true'
2.1.1.3. explicit conversion
Because of different representations, smaller types are not larger child types. If yes, there will be the following troubles:
1 // assume that the Code is not actually compiled: 2 val a: Int? = 1 // bind to Int (java. lang. Integer) 3 val B: Long? = A // implicitly converted to Long (java. lang. Long) 4 print (a = B) // surprising! When equals () checks that other parts are not Long, print "false"
So it's not just consistency, but it's also a part that will be silently lost here.
In this way, smaller types are not implicitly converted to larger types. This means that if no explicit type conversion is performed, the Byte type value cannot be assigned to the Int type variable.
1 val B: Byte = 1 // OK, static text check 2 val I: Int = B // Error
You can perform explicit numeric width conversion:
1 val I: Int = B. toInt () // OK: explicit width conversion
Each numeric type supports the following conversions:
ToByte (): Byte
-ToShort (): Short
-ToInt (): Int
-ToLong (): Long
-ToFloat (): Float
-ToDouble (): Double
-ToChar (): Char
Because the types are inferred from the context and the appropriate conversions overload the arithmetic operators, the absence of implicit conversions is rarely noticeable. For example:
1 val l = 1L + 3 // Long + Int => Long
2.1.1.4. Operation
The Kotlin development language supports a set of operations on digital standards, which are declared as corresponding class members (however, the compiler optimizes the corresponding commands for calling ). View: Operator overload (5.6 ).
As bitwise operations, there are no special features (characters) for them, and only naming functions allow them to be called in the infix mode, such:
1 val x = (1 shl 2) and 0x000FF000
This is a complete bitwise operation list (only valid for Int and Long types ):
-Shl (bits)-signed shift left (Java's <)
-Shr (bits)-signed shift right (Java's>)
-Ushr (bits)-unsigned shift right (Java's >>>)
-And (bits)-bitwise and
-Or (bits)-bitwise or
-Xor (bits)-bitwise xor
-Inv ()-bitwise inversion
2.1.2. Character
Char represents a character. They cannot be processed directly as Arrays:
1 fun check(c: Char) {2 if (c == 1) { // ERROR: incompatible types3 // ...4 }5 }
The character text is in single quotes: '1', '\ n',' \ uff00 '. We can clearly convert characters to Int numbers:
1 fun decimalDigitValue(c: Char): Int {2 if (c !in '0'..'9')3 throw IllegalArgumentException("Out of range")4 return c.toInt() - '0'.toInt() // Explicit conversions to numbers5 }
When a null reference is required, numbers and characters are boxed. The packing operation does not guarantee consistency.
2.1.3. Boolean Value
Boolean indicates a Boolean value. It has two values: true and false.
If a null reference is required, the Boolean value can be boxed.
The built-in operations of Boolean values include:
-|-Lazy separation (Note: This "lazy" does not know how to translate well, that is, "or" Why ?)
-&-Lazy connection
-! -Non
2.1.4. Array
In the Kotlin development language, the Array class represents an Array. It has get and set functions (converted to [] through the operator overload Convention), has the size attribute, and some other useful member functions:
1 class Array<T> private constructor() {2 val size: Int3 fun get(index: Int): T4 fun set(index: Int, value: T): Unit5 6 fun iterator(): Iterator<T>7 // ...8 }
You can use the database function arrayOf () to pass the values of the array to create an array, for example, arrayOf (, 3) to create an array [, 3]. Alternatively, use the arrayOfNulls () library function to create an array of the specified size. All the elements are filled with null.
Another option is to use the factory function to obtain the array size and return the initial values of the array elements at the specified index position:
1 // Creates an Array<String> with values ["0", "1", "4", "9", "16"]2 val asc = Array(5, { i -> (i * i).toString() })
As described above, the [] OPERATOR indicates calling the member functions get () and set ().
Note: Unlike the Java development language, in the Kotlin development language, arrays are invariant. This means that the kotlin development language does not allow the assignment of Array <String> to Array <Any>, which prevents possible running errors (however, you can use Array <out Any> to view: type Estimation (3.7.2 )).
The Kotlin development language also has a dedicated class that represents the array of the original type, and does not need to be packed and consumed: ByteArray, ShortArray, IntArray, and so on. These classes have no inheritance relationship with the Array class, but they have the same constructor method and attributes. Each of them has corresponding factory functions:
1 val x: IntArray = intArrayOf(1, 2, 3)2 x[0] = x[1] + x[2]
2.1.5. String
String type indicates a String. String is unchangeable. The element of the string is a character, which can be accessed through the index operation: s [I]. You can use the for loop to traverse a string:
1 for (c in str) {2 println(c)3 }
2.1.5.1. String text
The Kotlin development language has two types of string text: the escape string containing escape characters and the original string containing any characters and new line characters. Escape strings are very similar to Java development languages:
1 val s = "Hello, world!\n"
Escape can be implemented using a habitual method.
The original string is bounded by three quotation marks ("") and contains non-escape characters, newline characters, and other arbitrary characters:
1 val text = """2 for (c in "foo")3 print(c)4 """
2.1.5.2. String Template
A string can contain a template expression, that is, a code snippet that can be computed. The result is linked to the string. The template expression starts with the dollar sign ($) and forms a simple name:
1 val I = 102 val s = "I = $ I" // The result is "I = 10"
Or any expression in braces:
1 val s = "abc" 2 val str = "$ s. length is $ {s. length}" // The calculation result is "abc. length is 3"
Templates are supported in both the original and escape strings. To express $ characters, you can use the following syntax:
1 val price = "${'$'}9.99"
2.2. Package
A source file can start with the declaration package:
1 package foo.bar2 3 fun baz() {}4 class Goo {}5 // ...
All content (such as classes and functions) in the source file is included in the package declaration. Therefore, in the above example, the complete name of baz () is foo. bar. baz, and the complete name of Goo is foo. bar. Goo.
If no package is specified in the source file, the content in this file is a "default" package with no name.
2.2.1. import)
Except for the default import, each file can have its own import pseudo command. The Import syntax is described in the syntax (6.2.
You can import a single name, for example:
1 import foo.Bar // Bar is now accessible without qualification
It can also be all accessible content (packages, classes, objects, and so on) within the scope ):
1 import foo.* // everything in 'foo' becomes accessible
If there is a name conflict, you can use the as keyword to rename the conflict item to eliminate it:
1 import foo. Bar // Bar can access 2 import bar. Bar as bBar // bBar indicates 'bar. bar'
The import keyword does not limit the imported classes. It can also be used to import other declarations:
-- Top-level functions and attributes;
-- Functions and attributes declared in object Declaration (3.12.2;
-- Enumeration constant (3.11 );
Unlike the Java development language, the Kotlin development language does not have an independent "import static" syntax; all these statements are imported using the regular import keywords.
2.2.2. Visible Range of top-level declarations
If the top-level declaration annotation is private, it is private to the file where it is located (View: visibility modifier (3.4 ))
2.3. Control Flow 2.3.1. if expression
In the Kotlin development language, if is an expression, that is, it returns a value. Because normal if operations are good under this rule, there is no ternary operator (? : Else ).
1 // traditional usage 2 var max = a 3 if (a <B) 4 max = B 5 6 // with else 7 var max: Int 8 if (a> B) 9 max = a 10 else 11 max = B 12 13 // as expression 14 val max = if (a> B) a else B
If branch can be a code block, and the final expression is the value of the code block:
1 val max = if (a > b) { 2 print("Choose a") 3 a 4 } 5 else { 6 print("Choose b") 7 b 8 }
If you use if as an expression rather than a statement (for example, return its value or assign a value to a variable), the expression requires an else branch.
View: if syntax (6.2.3.4)
2.3.2. when expression
When replaces the switch operator similar to C development language. The simplest form is as follows:
1 when (x) {2 1 -> print("x == 1")3 2 -> print("x == 2")4 else -> { // Note the block5 print("x is neither 1 nor 2")6 }7 }
When the variable matches all the branches one by one until the branch that matches the condition is found. When can be used as an expression or a statement. The branch value that meets the condition is the value of the entire expression. If it is used as a statement, the values of individual branches are ignored. (Like if, each branch can be a code block, and the final expression value in the code block is its value .)
Else branch is equivalent to no other branch that meets the condition. If when is used as an expression and the compiler cannot verify that the branch condition overwrites all possible conditions, it is mandatory to require the else branch.
If the same processing method is available in multiple cases, you can also use commas to combine the branch conditions:
1 when (x) {2 0, 1 -> print("x == 0 or x == 1")3 else -> print("otherwise")4 }
Any expression (not just a constant) can be used as the branch condition:
1 when (x) {2 parseInt(s) -> print("s encodes x")3 else -> print("s does not encode x")4 }
You can also use in or! In checks a range (5.2) or set:
1 when (x) {2 in 1..10 -> print("x is in the range")3 in validNumbers -> print("x is valid")4 !in 10..20 -> print("x is outside the range")5 else -> print("none of the above")6 }
In another case, you can use is or! Is check special type. Note that, due to smart conversion (5.4), you can access the methods and attributes of the type without any additional checks:
1 val hasPrefix = when(x) {2 is String -> x.startsWith("prefix")3 else -> false4 }
When can also be used to replace the if-else chain. If there is no variable, the branch condition is a simple Boolean expression, and when the when condition is true, execute this branch:
1 when {2 x.isOdd() -> print("x is odd")3 x.isEven() -> print("x is even")4 else -> print("x is funny")5 }
View: when syntax (6.2.3.4.2.1 ).
2.3.3. for Loop
For Loop traversal provides any iterator. Syntax:
1 for (item in collection)2 print(item)
The loop body can be a code block.
1 for (item: Int in ints) {2 // ...3 }
As mentioned above, for loop traversal provides any iterator, namely:
-- Has a member iterator () or extended function iterator (), which returns the type:
-- Has a member next () or an extension function next (), and
-- HasNext () or hasNext (), a member of the boolean type, is returned ().
All three functions must be operators.
If you want to traverse an array or list using indexes, you can do this:
1 for (i in array.indices)2 print(array[i])
Note that this sentence "traversing a range" is implemented by the compiler optimization and does not need to generate additional objects.
Alternatively, you can use the withIndex library function:
1 for ((index, value) in array.withIndex()) {2 println("the element at $index is $value")3 }
View: for syntax (6.2.3.3 ).
2.3.4. while Loop
While and do... While works as usual:
1 while (x > 0) {2 x--3 }4 5 do {6 val y = retrieveData()7 } while (y != null) // y is visible here!
View: while syntax (6.2.3.3 ).
2.3.5. Loop interruption and Continuation
The Kotlin development language supports the traditional break and continue operators in the loop. View: return and redirect (2.4 ).
2.4. Return and redirect
The Kotlin development language has three structured jump operators:
-- Return. By default, it is returned by the nearest function or an anonymous function.
-- Break. Terminate the last loop.
-- Continue. Continue to the next step of the last loop.
2.4.1. Interrupt and continue tags
In the Kotlin development language, any expression can contain tags. The tag format is indicated by @ after the identifier. For example, abc @ and fooBar @ are all valid tags (View: syntax (6.2 )). To mark an expression, you only need to add a label before it:
1 loop@ for (i in 1..100) {2 // ...3 }
Now, you can break or continue to the tag:
1 loop@ for (i in 1..100) {2 for (j in 1..100) {3 if (...)4 break@loop5 }6 }
The break with the tag jumps to the execution point after the tag loop. Continue continues to mark the next step of loop.
2.4.2. Return at tag
The Kotlin development language allows function nesting in the function body, local functions, and object expressions. Return allows us to have external function responses. The most important use case is returned by a Lambda expression. Write the callback as follows:
1 fun foo() {2 ints.forEach {3 if (it == 0) return4 print(it)5 }6 }
The return expression is returned by the nearest function, that is, foo. (Note: in this way, Lambda expressions only support non-local return to embedded functions (4.1.5 ).) If you want to return data from a Lambda expression, you need to mark it to limit the return:
1 fun foo() {2 ints.forEach lit@ {3 if (it == 0) return@lit4 print(it)5 }6 }
Now, it is returned only from the Lambda expression. Generally, it is most convenient to use an implicit Tag: in this way, the tag has the same name as the function passed to the Lambda expression.
1 fun foo() {2 ints.forEach {3 if (it == 0) return@forEach4 print(it)5 }6 }
Alternatively, you can replace Lambda expressions with anonymous functions (4.2.3.3. The return statement in an anonymous function is returned from the anonymous function itself.
1 fun foo() {2 ints.forEach(fun(value: Int) {3 if (value == 0) return4 print(value)5 })6 }
When a value is returned, the parser gives an appropriate response first, for example:
1 return@a 1
"Return 1 at tag @ a" instead of "Return Tag expression (@ a 1 )".