Skip to content

函数声明语法 ​

text
Function := Visibility? "extension"? ReturnType? Identifier TypeParameters?
            "(" Parameters? ")" Block
Parameter := Type Identifier ("=" Expression)?
norm
Integer subtract(Integer left, Integer right) {
    return left - right
}

Extension function ​

extension 只修饰顶层函数,返回类型和至少一个参数必须显式声明。首参数是接收者,其余参数保留普通函数的标签规则。

norm
extension String quoted(String value) {
  return "\"" + value + "\""
}

String text = "Norm".quoted()

点号调用在绑定后成为普通函数调用,接收者作为第一个实参先求值。Extension 必须处于当前 package 或被显式 import;实例方法按名称优先,多个同等匹配的 extension 是编译错误。Extension 不进入类型的方法表或动态分派表。

Extension 按首参数的声明类型检查 nullable 接收者,不提前按实例解引用处理。例如首参数为 String? 时可以接收空值;期望 FieldHandle<T> 时可进行字段捕获。实例方法和函数类型字段仍遵守普通空值访问检查,不能通过同名 extension 绕过。

参数 ​

参数在函数体内是局部绑定。多参数调用使用 name: value,参数名因此属于 public API。单参数调用可以省略名称;多参数调用中的裸标识符只有与对应参数同名时才能省略标签。默认参数必须位于必填参数之后;省略实参时,默认表达式在调用位置按参数顺序求值。

参数标签决定结果绑定到哪个形参,但所有实参表达式始终按源码从左到右求值。未知、重复或缺失标签属于编译错误,name = value 不是调用语法。

norm
Integer result = subtract(left: 120, right: 100)

返回 ​

普通顶层函数省略返回类型时,声明类型固定为 Void。Extension 必须显式声明返回类型。class 方法省略返回类型时,声明类型固定为完整的 owner 类型;正常到达末尾和裸 return 产生 this,return value 非法。显式 Void 始终表示无结果。

除此之外,非 Void 具名函数的每条正常完成路径必须提供结果,可以使用 return value 或末尾表达式;末尾 if 的各分支遵循同一规则。interface 方法必须显式声明返回类型。Lambda 的末尾表达式规则见高级函数规则。

函数可以声明在模块顶层或类型内部。顶层函数不需要 class 容器,也不存在 static 修饰符。重载和函数值见高级函数规则。

这个可执行示例组合了具名实参、默认实参、同名实参简写、接口契约与 if 返回值:

norm
interface Formatter {
  String format(String text)
}

class PrefixFormatter implements Formatter {
  String prefix

  String format(String text) {
    return prefix + text
  }
}

class BareFormatter implements Formatter {
  String format(String text) {
    return text
  }
}

value Request {
  String text
  String audience = "team"
}

String deliver(Formatter formatter, Request request, String punctuation = "!") {
  String recipient = if request.audience == "team" { "all" } else { request.audience }
  return formatter.format(request.text) + punctuation + " for " + recipient
}

main() {
  Formatter formatter = PrefixFormatter(prefix: "Hello, ")
  Request request = Request(text: "Norm")
  printLine(deliver(formatter, request))
  printLine(deliver(request: Request(text: "Ada", audience: "agent"), punctuation: "?", formatter: formatter))
  Formatter bare = BareFormatter()
  printLine(deliver(formatter: bare, request: Request(text: "Ready", audience: "Ada")))

  String outcome = if request.audience == "team" {
    "broadcast"
  } else {
    "direct"
  }
  printLine(outcome)
}
text
Hello, Norm! for all
Hello, Ada? for agent
Ready! for Ada
broadcast

Norm 0.25