💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
Haxe允许许多类型的参数化,就像类字段(第4章)和枚举构造函数(第2.4.1节)。类型参数通过闭合的用逗号分隔的类型参数名尖括号来定义。一个简单的例子来自于Haxe标准库,就是 Array: > Haxe allows parametrization of a number of types, as well as class fields (4) and enum constructors (2.4.1). Type parameters are defined by enclosing comma-separated type parameter names in angle brackets <>. A simple example from the Haxe Standard Library is Array: ~~~ class Array<T> { function push(x : T) : Int; } ~~~ 每当一个Array的实例被创建,它的类型参数 T 成为一个 单形(第2.9节)。也就是说,它可以被绑定到任何类型,但是一次只有一个。这个绑定可以是显式的发生,通过调用构造函数使用显式的类型(new Array<String>()),或者隐式的发生,通过类型推断(第3.6节),例如当我们调用arrayInstance.push("foo") 。 > Whenever an instance of Array is created, its type parameter T becomes a monomorph (2.9). That is, it can be bound to any type, but only one at a time. This binding can happen explicitly by invoking the constructor with explicit types (new Array<String>()) or implicitly by type inference (3.6), e.g. when invoking arrayInstance.push("foo"). 一个类的定义内部使用类型参数,这些类型参数都是非特定的类型。除非约束(第3.2.1节)被添加,编译器必须假定类型参数可以被和任何类型一起使用。因此,不能访问类型参数的字段或者转换(第5.23)为一个类型参数类型。也不可能创建一个新的类型参数类型的实例,除非类型参数是泛型(第3.3节)并且被相应的约束。 > Inside the definition of a class with type parameters,these type parameters are an unspecific type. Unless constraints (3.2.1) are added, the compiler has to assume that the type parameters could be used with any type. As a consequence, it is not possible to access fields of type parameters or cast (5.23) to a type parameter type. It is also not possible to create a new instance of a type parameter type, unless the type parameter is generic (3.3) and constrained accordingly. 下面的表格显示允许类型参数的地方: > The following table shows where type parameters are allowed: |位置|绑定在|注意| | -- | -- | -- | |Class|实例化|也可以被绑定到成员字段访问上| |Enum|实例化|| |Enum构造函数|实例化|| |Function|调用中|允许用于方法和命名的局部 lvalue 函数| |Structure|实例化|| 使用函数类型参数被绑定到调用中,这样一个类型参数(如果无约束)接受任何类型。然而,每次调用只有一个类型被接受。这可以在有多个参数的函数中被利用: > With function type parameters being bound upon invocation, such a type parameter (if unconstrained) accepts any type. However, only one type per invocation is accepted. This can be utilized if a function has multiple arguments: ~~~ class Main { static public function main() { equals(1, 1); // runtime message: bar should be foo equals("foo", "bar"); // compiler error: String should be Int equals(1, "foo"); } static function equals<T>(expected:T, actual:T) { if (actual != expected) { trace(’$actual should be $expected’); } } } ~~~ equals函数所有预期的和实际的参数都有一个类型 T 。这意味着对于每个equals的调用,这两个参数必须是相同类型。编译器承认第一次调用(两种参数类型都是Int)和第二个调用(两个参数都是String),但是第三次尝试引发一个编译器错误。 > Both arguments expected and actual of the equals function have type T. This implies that for each invocation of equals the two arguments must be of the same type. The compiler admits the first call (both arguments being of Int) and the second call (both arguments being of String) but the third attempt causes a compiler error. **表达式语法中的类型参数** >[warning] **花絮**:表达式语法中的类型参数 我们经常遇到的问题,为什么一个方法使用类型参数不能被调用为 method<String>(x) 。编译器给出的错误信息不是非常有帮助的。然而,有一个简单的理由:上面的代码如果 < 和 > 都是二元操作符,将被解析产生 (method< Sting)>(x) 。 >[warning] **Trivia**: Type parameters in expression syntax We often get the question why a method with type parameters cannot be called as method<String>(x). The error messages the compiler gives are not very helpful. However,there is a simple reason forthat: The above code is parsed as if both < and > were binary operators, yielding (method < String) > (x).