Date
May. 20th, 2024
 
2024年 4月 13日

Post: Kotlin : Syntax

Kotlin : Syntax

Published 12:03 Mar 30, 2016.

Created by @ezra. Categorized in #Programming, and tagged as #Kotlin.

Source format: Markdown

Table of Content

前面对 Kotlin 的情况做了简单介绍,这一篇再来说说它的基本语法。

分号

首先可喜可贺的是,Kotlin 中语句末尾并不需要分号结尾。

基本类型

Kotlin 中的基本数据类型有:

类型位宽
Double 64
Float32
Long64
Int32
Short16
Byte8

位操作符

用于 IntLong 类型的位操作符:

  • shl(bits) : Java <<

  • shr(bits) : Java >>

  • ushr(bits) : Java >>>

  • and(bits) : 位与

  • or(bits) : 位或

  • xor(bits) : 位异或

  • inv() : 倒转

转义符

可以使用的转义符有:

  • \t

  • \b

  • \n

  • \r

  • \'

  • \"

  • \\

  • \$

包定义应该出现在文件最顶端:

package mine.demo

import java.util.*

// ...

这并不要求匹配目录,源文件可以放置在任意位置。

import foo.Bar
import foo.*
import foo.Bar
import bar.Bar as bBar

函数

Kotlin 中的函数使用 fun 关键字来定义,格式为:

fun 函数名(参数名一: 参数一类型, 参数名二: 参数二类型, 参数名三: 参数三类型 = 参数三默认值): 返回值类型 {
    // ...
    return ...
}

举个栗子,我们要计算两个数的和,于是我们定义一个返回 Int 值、接收两个 Int 参数的函数:

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

返回值的类型还可以通过推断来确定:

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

或者返回无意义的值:

fun printSum(a: Int, b: Int): Unit {
  print(a + b)
}

当然,既然是无意义的,那么 Unit 也是可以省略的:

fun printSum(a: Int, b: Int) {
  print(a + b)
}

调用函数也很简单:

val a = sum(1, 2)

也可以使用点符号(.):

Sample.foo()

对于只有一个参数的、使用 infix 关键字修饰的成员函数或扩展函数,还可以通过中缀形式,例如:

infix fun Int.shl(x: Int): Int {
    // ...
}

在使用时,下面这两行代码是等价的:

1 shl 2
1.shl(2)

本地变量

定义只读的单次赋值本地变量使用 val 关键字:

val a: Int = 1

同样可以使用类型推导:

val b = 1

定义时若没有初始化则必须指明类型:

val c: Int
c = 1

可变变量:

var x = 5
x += 1

属性

完整的属性定义语法是:

权限修饰 var 属性名称: 属性类型 = 初始化值
  [<getter>]
  [<setter>]

举个栗子:

public class Address {
  public var name: String = ...
  public var street: String = ...
  public var city: String = ...
  public var state: String? = ...
  public var zip: String = ...
}

fun copyAddress(address: Address): Address {
  val result = Address() // 实例化类时并不需要 new 关键字,事实上,Kotlin 中也不存在 new 这个关键字
  result.name = address.name
  result.street = address.street
  // ...
  return result
}

对于 getter 和 setter:

var stringRepresentation: String
  get() = this.toString()
  set(value) { // 如果你喜欢的话,也可以使用 value 意外的标识符
    setDataFromString(value)
  }
private var _table: Map<String, Int>? = null
public val table: Map<String, Int>
  get() {
    if (_table == null)
      _table = HashMap()
    return _table ?: throw AssertionError("Set to null by another thread")
  }

注释

Kotlin 中的注释与主流的其他语言类似,比如 C、Java、JavaScript:

// 单行注释,到行尾失效

/* 多行注释

    可以换行的哟 */

和 Java 不同的是,Kotlin 的多行注释是可以嵌套的。

注释还有一个重要的用途就是文档标记,例如

/**
 * A group of *members*.
 *
 * This class has no useful logic; it's just a documentation example.
 *
 * @param T the type of a member in this group.
 * @property name the name of this group.
 * @constructor Creates an empty group.
 */
class Group<T>(val name: String) {
    /**
     * Adds a [member] to this group.
     * @return the new size of the group.
     */
    fun add(member: T): Int { ... }
}

可以使用的标签有:

  • @param <name>

  • @return

  • @constructor

  • @property <name>

  • @throws <class>@exception <class>

  • @sample <identifier>

  • @see <identifier>

  • @author

  • @since

  • @suppress

对于行内标记,Kotlin 使用 标准 Markdown 语法

字符串模板

fun main(args: Array<String>) {
  if (args.size == 0) return

  print("First argument: ${args[0]}")

    val i = 10
    val s = "i = $i"

    val s = "abc"
    val str = "$s.length is ${s.length}"

    val price = """
    ${'$'}9.99
    """
}

if 判断

通常我们会这样使用:

fun max(a: Int, b: Int): Int {
  if (a > b)
    return a
  else
    return b
}

在 Kotlin 中,上面的代码还可以这样写:

fun max(a: Int, b: Int) = if (a > b) a else b

可空类型

当一个值可能为 null 时,要明确的标明,例如:

fun parseInt(str: String): Int? {
  // ...
}

类型判断

使用 is 关键字可以判断一个表达式的值是否为某个类型的实例。

fun getStringLength(obj: Any): Int? {
  if (obj is String) {
    // 此处 `obj` 被自动转换为 `String`
    return obj.length
  }

  // `obj` 在类型检查分支外依然为 `Any`
  return null
}

对于 is 关键字,你还可以使用 ! 操作符达到 "is not" 的效果:

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

  return obj.length
}

for in 循环

你可以这样使用 for in 循环:

fun main(args: Array<String>) {
  for (arg in args)
    print(arg)
}
for ((index, value) in array.withIndex()) {
    println("the element at $index is $value")
}

当然,你可以在遍历内容时额外添加类型:

for (item: Int in ints) {
  // ...
}

while 循环

fun main(args: Array<String>) {
  var i = 0
  while (i < args.size)
    print(args[i++])
}

do while 循环

do {
  val y = retrieveData()
} while (y != null) // y 在这里是可以使用的!

范围

范围(range)使用 起始值..结尾值 的格式书写,例如:

if (x in 1..y-1)
  print("OK")

你还可以使用 downTostep 关键字做更多限定:

for (i in 1..4 step 2) print(i) // 输出 "13"
for (i in 4 downTo 1 step 2) print(i) // 输出 "42"

when 匹配

fun cases(obj: Any) {
  when (obj) {
    1          -> print("One")
    0, 2         -> print("x == 0 or x == 1")
    in 1..10     -> print("x is in the range")
    foo(s)       -> print("foo")
    "Hello"    -> print("Greeting")
    is Long    -> print("Long")
    !is String -> print("Not a string")
    else       -> print("Unknown")
  }
}
Pinned Message
HOTODOGO
I'm looking for a SOFTWARE PROJECT DIRECTOR / SOFTWARE R&D DIRECTOR position in a fresh and dynamic company. I would like to gain the right experience and extend my skills while working in great teams and big projects.
Feel free to contact me.
For more information, please view online résumé or download PDF
本人正在寻求任职 软件项目经理 / 软件技术经理 岗位的机会, 希望加⼊某个新鲜⽽充满活⼒的公司。
如有意向请随时 与我联系
更多信息请 查阅在线简历下载 PDF