Skip to content

Latest commit

 

History

History
99 lines (74 loc) · 4.75 KB

2.6.函数类型.md

File metadata and controls

99 lines (74 loc) · 4.75 KB

2.6.函数类型

函数类型与 单形(第2.9节) 都是一个类型,尽管他们无处不在,但是这两种类型都被很好的隐藏了起来。我们可以使用 一个特殊的 Haxe 标识符 $type 来使得隐藏其后类型浮出水面,它可以在编译时输出它所持表达式的类型:

class Main { 
    static public function main() {
        $type(test); // i : Int -> s : String -> Bool
        $type(test(1, "foo")); // Bool 
    } 
    static function test(i:Int, s:String):Bool {
        return true; 
    } 
} 

第一条 $type 表达式的输出与 test 的函数声明十分相似,同时也有微妙的区别:函数参数被特殊的箭头符号 -> 而不是逗号 , 所分隔,且函数返回类型出现在结尾的另一个 -> 符号之后。

不论哪个记法,很明显,函数 test 接受第一个 Int 类型的参数,第二个 String 类型的参数,并返回一个 Bool 类型值。如果调用这个函数,例如 test(1,"foo"),并将其放在第二个 $type 语句中,Haxe 类型检查器将会检查 1 是否可以被赋值到 Int 类型参数,然后检查 "foo" 是否可以被赋值到 String 类型参数,检查通过之后函数调用的结果就会和 test 函数返回值的类型相同,即,一个 Bool 类型。

如果一个函数类型有其它函数类型的参数或者返回值,则可以使用括号对它们进行正确的分组。例如,Int->(Int->Void)->Void 表示一个函数,第一个参数为 Int 类型,第二个参数是函数 Int->Void 类型,返回 Void

2.6.1.可选参数

可选参数通过在参数标识符前面前置一个问号 ? 来声明:

 class Main {
    static public function main() { 
        // ?i : Int -> ?s : String -> String 
        $type(test);
        trace(test()); // i: null, s: null 
        trace(test(1)); // i: 1, s: null 
        trace(test(1, "foo")); // i: 1, s: foo 
        trace(test("foo")); // i: null, s: foo 
    } 
    static function test(?i:Int, ?s:String) { 
        return "i: " +i + ", s: " +s;
    } 
} 

函数 test 有两个可选参数:Int 类型的 i 和 String 类型的 s 。这在第3行的函数类型输出直接反映出来。这个例子程序调用了4次 test ,并打印出它的返回值:

  • 第一次调用不带任何参数
  • 第二次调用带有一个单独的参数 1
  • 第三次调用带了两个参数 1 和 "foo"
  • 第四次调用只有单独的参数 “foo

输出内容显示,函数调用中被省略的可选参数的值为 null 。这意味着这些参数的类型必须能够接受 null 作为其值,这个问题在 为空性(第2.2节) 中详细讨论。Haxe 编译器会确保当编译至 静态目标平台(第2.2节)时,基本类型的可选参数被推断为Null<T> 使得其成为一个 “可空的” 类型。

前三个调用非常直观,第四个调用可能显得有些意外:如果当前位置提供的值可以被赋值给下一个位置的参数时,则允许跳过可选参数直接赋值给下一个位置的参数。

补充:跳过可选参数的规则是可传递的,比如

static function test(?i:Int, ?f:Float, ?s:String)
{
	trace(s);
}
//当调用 test("foo"); 时将会输出 “foo” 

2.6.2.默认值

Haxe 允许通过分配一个常量值来为参数提供默认值,:

 class Main { 
    static public function main() { 
        // ?i : Int -> ?s : String -> String 
        $type(test);
        trace(test()); // i: 12, s: bar 
        trace(test(1)); // i: 1, s: bar 
        trace(test(1, "foo")); // i: 1, s: foo 
        trace(test("foo")); // i: 12, s: foo
    } 
    static function test(?i = 12, s = "bar") {
        return "i: " +i + ", s: " +s;
    } 
} 

这个示例和前面 可选参数(第2.6.1节) 中的非常相似,唯一的区别是函数的参数 is 分别被赋值为 12 和 “bar”。效果为以默认值取代 null ,可以在调用时省略某个参数。Haxe 中的默认值并不是类型的一部分,而且不能在调用时更改函数的默认值(意指只应用于当次调用,而不会改变函数的默认值定义。除非函数是 内联(第4.4.2节) 的,被认为是一个比较典型的处理)。在一些目标语言中,编译器仍可能会传递 null 值作为省略的参数值,生成类似于下面所示的代码到函数中:

 static function test(i = 12, s = "bar") { 
    if (i == null) i = 12;
    if (s == null) s = "bar";
    return "i: " +i + ", s: " +s;
} 

在对性能有要求的代码中这个问题需要被考虑到,因为没有默认值的解决方案有时可能更可行。