haxe 第一期 入门骗 (谷歌翻译+转载)
2017-10-20 00:57
120 查看
/*
欢迎在15分钟内学习Haxe 3。http://www.haxe.org
这是一个可执行的教程。
您可以使用haxe编译器编译并运行它,
而在与LearnHaxe.hx相同的目录中: haxe -main LearnHaxe3 -x out
(只是把老外的文章谷歌翻译了而已,然后稍微整理了一下,可能有漏洞,还是推荐去看原文)
(欢迎看原汁原味原网址,垃圾的我表示看不懂英文)
https://github.com/jdonaldson/learnxinyminutes-docs/blob/master/haxe.html.markdown
(附上一个看到的博客,里面文章对大家应该有帮助)
http://blog.csdn.net/rocks_lee/article/details/10166573
*/
//我们从评论开始...这是一个单行评论
/*
这是多行的。多行注释也用于为haxedoc生成javadoc风格的文档。
如果它们在类,类函数或类变量之前,它们将被使用。(传说中的代码提示)
*/
/*
这是你第一个实际的haxe代码,它宣布一个空的包。
一个包不是必需的,
但是如果要为代码创建一个命名空间
(例如org.module.ClassName),这是非常有用的。*/
package; //空包,没有命名空间。
/*
如果从其他文件导入代码,则必须在其余
代码
之前声明。*/
import haxe.ds.ArraySort ;
//您可以使用“*”
import haxe.ds. * 一次导入许多类/模块;
/* 您还可以以特殊方式导入类,使其能够扩展 其他类的功能。*/
using StringTools ;
/* Typedefs类似于变量...。它们必须在任何代码之前声明。 */
typedef FooString = String;
// Typedefs也可以使用“结构”类型,更多的也在以后!
typedef FooObject = { foo: String } ;
class LearnHaxe01{
/*
如果你希望某些代码自动运行,你需要把它放在
一个静态的主要功能,并在编译器参数指定类。
在这种情况下,我们在上面的编译器参数中指定了“LearnHaxe3”类。 */
static function main(){
/*
Trace是将haxe表达式打印到屏幕的默认方法。
不同的目标将有不同的实现方法。例如,java,c ++,c#等将打印出来。
Javascript将打印到console.log,flash将打印到一个嵌入的TextField。
所有痕迹都附带默认换行符。
最后,可以通过使用编译器上的“--no-traces”参数来防止跟踪显示。 */
trace("Hello World, with trace()!");
/*
Trace可以处理任何类型的值或对象。它将尝试最好地打印
表达式的表示。您也可以连接字符串用“+”操作符:
*/
trace(
" Integer: " + 10 +
" Float: " + 3.14 +
" Boolean: " + true
);
/*新增 抛出错误*/
try
{
throw "invalid foo"; //抛出错误后记得关闭运行的文件,否则一直编译报错,不明所以
}catch (e:String){} //不同于as3的抛出错误
/*新增 确定值类型*/
var a:Int = 0;
$type(a); //能输出值的类型,但是会报错
/*
记住我所说的表达式需要分号吗?
如果需要,您可以在一行上放置多个表达式。
*/
trace('two expressions..'); trace('one line');
////////////////////////////////////////////////// ////////////////
//类型和变量
/////////////////////////// /////////////////////
trace("***Types & Variables***");
/* 可以使用 “var”关键字保存数据结构的值和引用*/
var an_integer:Int = 1;
trace(an_integer + ' is the value for $an_integer');
/*新增 注意上面这行代码,在字符串中加了一个 $ 后面接变量名就可以代表变量了
* 注意 仅在单引号内有效
* */
/*
Haxe是静态类型的,所以“an_integer”被声明为具有“Int”类型,而其余的表达式将赋值为“1”
。在许多情况下不需要声明类型。这里,haxe编译器推断another_integer的类型应该是“Int”。
*/
var another_integer = 2;
trace(another_integer + " is the value for another_integer");
// $ type()方法打印编译器分配的类型:
$type(another_integer);
//您也可以用十六进制表示整数:
var hex_integer = 0xffffff;
/*
Haxe使用Int和Float尺寸的平台精度。
它还使用平台行为溢出。
(使用特殊库可以使用其他数字类型和行为) */
/*
除了诸如整数,浮点数和布尔值之类的简单值之外,
Haxe为常见的数据结构(如字符串,数组,列表和映射)提供标准库实现: */
var a_string = "some" + 'string'; //字符串可以有双引号或单引号,好像在调用的时候也没啥差别
trace(a_string + " is the value for a_string");
var x = 1;
var an_interpolated_string = 'the value of x is $x';
/*
字符串是不可变的,实例方法将返回部分或全部字符串的副本。
(另请参见StringBuf类)。
*/
var a_sub_string = a_string.substr(0,4);
trace(a_sub_string + " is the value for a_sub_string");
/*
数组是零索引的,动态的和可变的。缺少值被
定义为null。
*/
/*新增 注意这里
*
* 在as3中,通常我们在写数组时会
*
* var arr:Array = new Array();
*
* 但是在haxe里,这样是错误的,而且
*
* var a:Array = new Array<String>();
*
* 这样写同样会报错
*
* */
var a = new Array<String>(); //包含字符串
a[0] = 'foo';
trace(a.length + " is the value for a.length");
a[9] = 'bar';
trace(a.length + " is the value for a.length (after modification)");
trace(a[3] + " is the value for a[3]");
/* 数组是*通用*,所以你可以用一个类型参数来指出它们包含的值: */
var a2 = new Array<Int>();// Ints的数组
var a3 = new Array<Array<String>>(); //数组数组(字符串)。
/* 地图是简单的键/值数据结构。键和值可以是任何类型。 */
var m = new Map<String, Int>(); //键是字符串,值是Ints。
m.set('foo', 4);
//你也可以使用数组符号;
/*新增 注释 总觉得这东西有点像dictionary
* 你可以通过一下几个方法访问m
* m['foo'];
* m.get("foo");
* */
m['bar'] = 5;
/*确定一个键值是否存在*/
trace(m.exists('bar') + " is the value for m.exists('bar')");
trace(m.get('bar') + " is the value for m.get('bar')");
trace(m['bar'] + " is the value for m['bar']");
/*新增 注释 可以用下面这种方法来添加数据*/
var m2 = ['foo' => 4, 'baz' => 6]; // Alternative map syntax
trace(m2 + " is the value for m2");
/*
记住,你可以使用类型推断。Haxe编译器将
在您首次传递设置类型参数的参数时决定变量的类型。 */
var m3 = new Map();
m3.set(6, 'baz'); // m3 is now a Map<Int,String>
trace(m3 + " is the value for m3");
/*
Haxe在haxe.ds模块中有更多常见的数据结构,例如
List,Stack和BalancedTree
*/
////////////////////////////////////////////////// ////////////////
//操作员
///////////////////////////// ////////////////////
trace("***OPERATORS***");
//基本算术
trace((4 + 3) + " is the value for (4 + 3)");
trace((5 - 1) + " is the value for (5 - 1)");
trace((2 * 4) + " is the value for (2 * 4)");
trace((8 / 4) + " is the value for (8 / 3) (division always produces Floats)");
trace((12 % 4) + " is the value for (12 % 4)");
//基本比较
trace((3 == 2) + " is the value for 3 == 2");
trace((3 != 2) + " is the value for 3 != 2");
trace((3 > 2) + " is the value for 3 > 2");
trace((3 < 2) + " is the value for 3 < 2");
trace((3 >= 2) + " is the value for 3 >= 2");
trace((3 <= 2) + " is the value for 3 <= 2");
//按位运算符
/*
~ Unary bitwise complement
<< Signed left shift
>> Signed right shift
>>> Unsigned right shift
& Bitwise AND
^ Bitwise exclusive OR
| Bitwise inclusive OR
*/
// increment
var i = 0;
trace("Increments and decrements");
trace(i++); //i = 1. Post-Incrementation
trace(++i); //i = 2. Pre-Incrementation
trace(i--); //i = 1. Post-Decrementation
trace(--i); //i = 0. Pre-Decrementation
////////////////////////////////////////////////// ////////////////
//控制结构
//////////////////////////// ////////////////////
trace("***CONTROL STRUCTURES***");
// if statements
var j = 10;
if (j == 10){
trace("this is printed");
} else if (j > 10){
trace("not greater than 10, so not printed");
} else {
trace("also not printed.");
}
// there is also a "ternary" if:
(j == 10) ? trace("equals 10") : trace("not equals 10");
/*
最后,还有一种形式的控制结构
在编译时运行:条件编译。
*/
#if neko
trace('hello from neko');
#elseif js
trace('hello from js');
#else
trace('hello from another platform!');
#end
/*
编译后的代码将根据平台目标而有所不同。
由于我们正在为neko(-x或-neko)进行编译,所以我们只得到了neko的
问候语。
*/
trace("循环和迭代");
// while loop
var k = 0;
while(k < 100){
// trace(counter); //将打印出数字0-99
k++;
}
// do-while loop
var l = 0;
do{
trace("do statement always runs at least once");
} while (i > 0);
// 循环
/*
Haxe中没有c-style for循环,因为它们容易出错,而不是必需的。
相反,Haxe有一个使用迭代器的更简单和更安全的版本(更多在以后)。
*/
var m = [1,2,3];
for (val in m){
trace(val + " is the value for val in the m array");
}
//请注意,您可以使用范围
var n = ['foo', 'bar', 'baz'];
for (val in 0...n.length){
trace(val + " is the value for val (an index for m)");
}
trace("Array Comprehensions");
//数组解析使您能够遍历数组
//同时创建过滤器和修改。
var filtered_n = [for (val in n) if (val != "foo") val];
trace(filtered_n + " is the value for filtered_n");
var modified_n = [for (val in n) val += '!'];
trace(modified_n + " is the value for modified_n");
var filtered_and_modified_n = [for (val in n) if (val != "foo") val += "!"];
trace(filtered_and_modified_n + " is the value for filtered_and_modified_n");
////////////////////////////////////////////////// //////////////
// //切换语句(值类型)
//////////////////////// //////////////////////
trace("***SWITCH STATEMENTS (VALUE TYPES)***");
/*
在Haxe中的切换语句非常强大。除了处理
诸如字符串和int之类的基本值之外,它们还可以处理
枚举中的广义代数数据类型(稍后更多的枚举)。
这里有一些基本的价值实例:
*/
/*新增 注释 注意这里 switch语句没有break 要注意这里和其他语言的区别
* 但是我们可以这样写 case 1,2 用逗号把选项分开
* */
var my_dog_name = "fido";
var favorite_thing = "";
switch(my_dog_name){
case "fido" : favorite_thing = "bone";
case "rex" : favorite_thing = "shoe";
case "spot" : favorite_thing = "tennis ball";
default : favorite_thing = "some unknown treat";
// case _ : "some unknown treat"; // same as default
}
//上面的“_”一个“通配符”值,将匹配任何东西。相当于default
race("My dog's name is" + my_dog_name
+ ", and his favorite thing is a: "
+ favorite_thing);
////////////////////////////////////////////////// ////////////////
//表达陈述
//////////////////////////// ////////////////////
trace("***表达声明***");
/* Haxe控制语句非常强大,因为每个语句也是一个表达式*/
/*新增 注释 太强大 先吃一粒定心丸,可能有点颠覆我们的习惯*/
// if statements
var k = if (true){
10;
} else {
20;
}
trace("K equals ", k); //输出10
var other_favorite_thing = switch(my_dog_name) {
case "fido" : "teddy";
case "rex" : "stick";
case "spot" : "football";
default : "some unknown treat";
}
trace("My dog's name is" + my_dog_name
+ ", and his other favorite thing is a: "
+ other_favorite_thing);
////////////////////////////////////////////////// //////////////
// //转换价值类型
/////////////////////////// /////////////////////
trace("***转换类型***");
//您可以很容易地将字符串转换为int。
// string to integer
Std.parseInt("0"); //返回0
Std.parseFloat("0.4"); //返回0.4;
// integer to string
Std.string(0); //返回“0”;
//串联与字符串将自动转换为字符串。
0 + ""; //返回“0”;
true + ""; //返回“true”;
//有关详细信息,请参阅Std中的解析文档。
/*新增 注释 Std 这个类提供了一些常用的数值运算 可以点进入类看看,方法不是很多,且提供了类型判断
* 在as3中 我比较习惯直接 用is 来判断类型,
* 但是在haxe中 is会报错,
* 但是我们可以使用 Std.is(123.1315,Int); 来判断
* */
////////////////////////////////////////////////// ////////////////
//处理类型
/////////////////////////// /////////////////////////////////////
/*
如前所述,Haxe是一种静态类型的语言。总而言之
,静态打字是一件奇妙的事情。
它启用自动完成,可以非常彻底地检查程序的正确性。
另外,Haxe编译器超级快。你可能不会在等待它了。
*无论如何*,有时您只希望编译器会让
某些东西滑动,而不要在有限的情况下抛出类型错误。
为了做到这一点,Haxe有两个单独的关键字。第一个是
“Dynamic”类型:
*/
var dyn: Dynamic = "any type of variable, such as this string";
/*
所有你知道的一个动态变量是
编译器不再担心它是什么类型。它就像一个
通配符变量:你可以传递它,而不是任何变量类型,
你可以分配任何你想要的变量类型。
另一个更极端的选项是“无类型”关键字
*/
untyped {
var x:Int = 'foo';
var y:String = 4;
}
/*
untyped关键字在整个* block *代码上运行,跳过
任何可能需要的类型检查。该关键字应该
非常谨慎地使用,例如在有条件编译的
情况下,类型检查是一种阻碍。
一般来说,跳过类型检查是*不*推荐。使用
枚举,继承或结构类型模型来验证程序的正确性。
只有当您确定所有类型型号都不工作时,您应该使用“动态”或“无类型”。 */
////////////////////////////////////////////////// //////////////
//基础面向对象编程
////////////////////////// ////////////////////
trace("***基于对象的面向对象编程***");
/*
创建一个FooClass的实例。这些类在文件的末尾。 */
var instance = new FooClass(3);
//读取公共变量通常
trace(instance.public_any + " is the value for instance.public_any");
//我们可以读此变量
trace(instance.public_read + " is the value for instance.public_read");
//但不写它
// instance.public_write = 4; //如果取消注释,这将抛出一个错误:
// trace(instance.public_write); //就这样
trace(instance + " is the value for instance"); //调用toString方法
trace(instance.toString() + " is the value for instance.toString()"); // 一样
/*
实例具有“FooClass”类型,而acceptBaseFoo具有
BaseFooClass类型。但是,由于FooClass扩展了BaseFooClass,
所以被接受。
*/
BaseFooClass.acceptBaseFoo(instance);
/*
下面的类有一些更高级的例子,“example()”
方法将在这里运行。
*/
SimpleEnumTest.example();
ComplexEnumTest.example();
TypedefsAndStructuralTypes.example();
UsingExample.example();
}
}
/*
这是主要的LearnHaxe3类的“子类”
*/
class FooClass extends BaseFooClass implements BaseFooInterface{
public var public_any:Int; //公共变量是随时随地访问
public var public_read (default,null): Int; //使用此样式仅启用公共读取
public var public_write (null, default): Int; //或public write
public var property (get, set): Int; //使用此样式来启用getter / setter
//私有变量在类之外是不可用的。
// see @:allow for around around this。
var _private:Int; //如果变量未标记为public,则变量为private
// public
public function new(arg:Int){
super(); //调用父对象的构造函数,因为我们扩展了BaseFooClass
this.public_any= 0;
this._private = arg;
}
// getter for _private
function get_property() : Int {
return _private;
}
// setter for _private
function set_property(val:Int) : Int {
_private = val;
return val;
}
//每当将实例转换为字符串时调用的特殊函数。
public function toString(){
return _private + " with toString() method!";
}
//这个类需要定义这个函数,因为它实现了BaseFooInterface接口。
public function baseFunction(x: Int) : String{
// convert the int to string automatically
return x + " was passed into baseFunction!";
}
}
/*
一个简单的类来扩展
*/
class BaseFooClass {
var base_variable:Int;
public function new(){
base_variable = 4;
}
public static function acceptBaseFoo(b:BaseFooClass){
}
}
/*
一个简单的接口来实现
*/
interface BaseFooInterface{
public function baseFunction(x:Int):String;
}
////////////////////////////////////////////////// //////////////
//枚举和切换语句
////////////////////////// //////////////////////////////////////
/* Haxe中的枚举非常强大。枚举是最简单的形式,它是一个数量有限的类型:*/
enum SimpleEnum {
Foo;
Bar;
Baz;
}
//这是一个使用它的类:
class SimpleEnumTest{
public static function example(){
var e_explicit:SimpleEnum = SimpleEnum.Foo; //可以指定“完整”名称
var e = Foo ; //但推论也会奏效。
switch(e){
case Foo: trace("e was Foo");
case Bar: trace("e was Bar");
case Baz: trace("e was Baz"); // 注释此行以抛出错误。
}
/*
这与字符串上的简单值开关看起来没有什么不同。
但是,如果我们不包括* all *的状态,
编译器会抱怨。您可以通过注释上面的一行来尝试。
您还可以为枚举开关指定默认值:
*/
switch(e){
case Foo: trace("e was Foo again");
default : trace("default works here too");
}
}
}
/*
枚举远远超过简单的状态,
我们也可以枚举 *构造函数*,
但是我们需要一个更复杂的枚举例子
*/
enum ComplexEnum{
IntEnum(i:Int);
MultiEnum(i:Int, j:String, k:Float);
SimpleEnumEnum(s:SimpleEnum);
ComplexEnumEnum(c:ComplexEnum);
}
//注意:上面的枚举可以包括*其他*枚举,包括自己!
class ComplexEnumTest{
public static function example(){
var e1:ComplexEnum = IntEnum(4); //指定枚举参数
/* 现在我们可以打开枚举,并提取它可能有的任何参数。 */
switch(e1){
case IntEnum(x) : trace('$x was the parameter passed to e1');
default: trace("Shouldn't be printed");
}
//这里的另一个参数本身就是枚举枚举枚举?
var e2 = SimpleEnumEnum(Foo);
switch(e2){
case SimpleEnumEnum(s): trace('$s was the parameter passed to e2');
default: trace("Shouldn't be printed");
}
//枚举一路向下
var e3 = ComplexEnumEnum(ComplexEnumEnum(MultiEnum(4, 'hi', 4.3)));
case ComplexEnumEnum(ComplexEnumEnum(MultiEnum(i,j,k))) : {
trace('$i, $j, and $k were passed into this nested monster');
}
default: trace("(“不应打印”");
}
/* 查看“广义代数数据类型”(GADT),了解更多关于为什么这么大的细节。 */
}
}
class TypedefsAndStructuralTypes {
public static function example(){
//这里我们要使用typedef类型,而不是基类型。
var t1:FooString = "some string";
/*
我们可以使用typedef作为“结构类型”。
这些类型由它们的字段结构定义,而不是类继承。
这是一个名为“foo”的String字段的匿名对象:*/
var fooObj = { foo: 'hi' };
/*
记住在我们宣布FooObj typedef的顶部?
由于fooObj与该结构相匹配,
所以我们可以在任何需要“FooObject”的地方使用它。 */
var f = function(fo:FooObject){
trace('$fo was passed in to this function');
}
f(fooObj); //用fooObj调用FooObject签名函数。
/*
请注意,typedef还可以包含可选字段,标有“?”
typedef OptionalFooObj = {
?optionalString: String,
requiredInt: Int
}
*/
/*
Typedef与条件编译工作良好。例如,
我们可以将其包含在文件的顶部:
#if(js)
typedef Surface = js.html.CanvasRenderingContext2D;
#elseif(nme)
typedef Surface = nme.display.Graphics;
#elseif(!flash9)
typedef Surface = flash8.MovieClip;
#elseif(java)
typedef Surface = java.awt.geom.GeneralPath;
#结束
这将给我们一个单一的“表面”类型,以便在所有这些平台上使用。
*/
}
}
class UsingExample {
public static function example() {
/*
“using”import关键字是一种特殊的类导入,
它改变了类中任何静态方法的行为。
在这个文件中,我们将“using”应用于“StringTools”,
它包含了一些用于处理String类型的静态方法。
*/
trace(StringTools.endsWith("foobar", "bar") + " should be true!");
/*
使用“using”导入时,第一个参数类型将使用该
方法进行扩展。这意味着什么?那么,既然“的endsWith”具有第一 “字符串”,
这意味着所有的字符串类型现在有的参数类型“的endsWith”的方法:
*/
trace("foobar".endsWith("bar") + " should be true!");
/*
这种技术可以为某些类型提供很好的表达,
同时限制对单个文件的修改范围。
请注意,String实例在运行时是*不*修改。
新附加的方法不是附加
实例的一部分,编译器仍然生成等效于静态方法的代码。
*/
}
}
欢迎在15分钟内学习Haxe 3。http://www.haxe.org
这是一个可执行的教程。
您可以使用haxe编译器编译并运行它,
而在与LearnHaxe.hx相同的目录中: haxe -main LearnHaxe3 -x out
(只是把老外的文章谷歌翻译了而已,然后稍微整理了一下,可能有漏洞,还是推荐去看原文)
(欢迎看原汁原味原网址,垃圾的我表示看不懂英文)
https://github.com/jdonaldson/learnxinyminutes-docs/blob/master/haxe.html.markdown
(附上一个看到的博客,里面文章对大家应该有帮助)
http://blog.csdn.net/rocks_lee/article/details/10166573
*/
//我们从评论开始...这是一个单行评论
/*
这是多行的。多行注释也用于为haxedoc生成javadoc风格的文档。
如果它们在类,类函数或类变量之前,它们将被使用。(传说中的代码提示)
*/
/*
这是你第一个实际的haxe代码,它宣布一个空的包。
一个包不是必需的,
但是如果要为代码创建一个命名空间
(例如org.module.ClassName),这是非常有用的。*/
package; //空包,没有命名空间。
/*
如果从其他文件导入代码,则必须在其余
代码
之前声明。*/
import haxe.ds.ArraySort ;
//您可以使用“*”
import haxe.ds. * 一次导入许多类/模块;
/* 您还可以以特殊方式导入类,使其能够扩展 其他类的功能。*/
using StringTools ;
/* Typedefs类似于变量...。它们必须在任何代码之前声明。 */
typedef FooString = String;
// Typedefs也可以使用“结构”类型,更多的也在以后!
typedef FooObject = { foo: String } ;
class LearnHaxe01{
/*
如果你希望某些代码自动运行,你需要把它放在
一个静态的主要功能,并在编译器参数指定类。
在这种情况下,我们在上面的编译器参数中指定了“LearnHaxe3”类。 */
static function main(){
/*
Trace是将haxe表达式打印到屏幕的默认方法。
不同的目标将有不同的实现方法。例如,java,c ++,c#等将打印出来。
Javascript将打印到console.log,flash将打印到一个嵌入的TextField。
所有痕迹都附带默认换行符。
最后,可以通过使用编译器上的“--no-traces”参数来防止跟踪显示。 */
trace("Hello World, with trace()!");
/*
Trace可以处理任何类型的值或对象。它将尝试最好地打印
表达式的表示。您也可以连接字符串用“+”操作符:
*/
trace(
" Integer: " + 10 +
" Float: " + 3.14 +
" Boolean: " + true
);
/*新增 抛出错误*/
try
{
throw "invalid foo"; //抛出错误后记得关闭运行的文件,否则一直编译报错,不明所以
}catch (e:String){} //不同于as3的抛出错误
/*新增 确定值类型*/
var a:Int = 0;
$type(a); //能输出值的类型,但是会报错
/*
记住我所说的表达式需要分号吗?
如果需要,您可以在一行上放置多个表达式。
*/
trace('two expressions..'); trace('one line');
////////////////////////////////////////////////// ////////////////
//类型和变量
/////////////////////////// /////////////////////
trace("***Types & Variables***");
/* 可以使用 “var”关键字保存数据结构的值和引用*/
var an_integer:Int = 1;
trace(an_integer + ' is the value for $an_integer');
/*新增 注意上面这行代码,在字符串中加了一个 $ 后面接变量名就可以代表变量了
* 注意 仅在单引号内有效
* */
/*
Haxe是静态类型的,所以“an_integer”被声明为具有“Int”类型,而其余的表达式将赋值为“1”
。在许多情况下不需要声明类型。这里,haxe编译器推断another_integer的类型应该是“Int”。
*/
var another_integer = 2;
trace(another_integer + " is the value for another_integer");
// $ type()方法打印编译器分配的类型:
$type(another_integer);
//您也可以用十六进制表示整数:
var hex_integer = 0xffffff;
/*
Haxe使用Int和Float尺寸的平台精度。
它还使用平台行为溢出。
(使用特殊库可以使用其他数字类型和行为) */
/*
除了诸如整数,浮点数和布尔值之类的简单值之外,
Haxe为常见的数据结构(如字符串,数组,列表和映射)提供标准库实现: */
var a_string = "some" + 'string'; //字符串可以有双引号或单引号,好像在调用的时候也没啥差别
trace(a_string + " is the value for a_string");
var x = 1;
var an_interpolated_string = 'the value of x is $x';
/*
字符串是不可变的,实例方法将返回部分或全部字符串的副本。
(另请参见StringBuf类)。
*/
var a_sub_string = a_string.substr(0,4);
trace(a_sub_string + " is the value for a_sub_string");
/*
数组是零索引的,动态的和可变的。缺少值被
定义为null。
*/
/*新增 注意这里
*
* 在as3中,通常我们在写数组时会
*
* var arr:Array = new Array();
*
* 但是在haxe里,这样是错误的,而且
*
* var a:Array = new Array<String>();
*
* 这样写同样会报错
*
* */
var a = new Array<String>(); //包含字符串
a[0] = 'foo';
trace(a.length + " is the value for a.length");
a[9] = 'bar';
trace(a.length + " is the value for a.length (after modification)");
trace(a[3] + " is the value for a[3]");
/* 数组是*通用*,所以你可以用一个类型参数来指出它们包含的值: */
var a2 = new Array<Int>();// Ints的数组
var a3 = new Array<Array<String>>(); //数组数组(字符串)。
/* 地图是简单的键/值数据结构。键和值可以是任何类型。 */
var m = new Map<String, Int>(); //键是字符串,值是Ints。
m.set('foo', 4);
//你也可以使用数组符号;
/*新增 注释 总觉得这东西有点像dictionary
* 你可以通过一下几个方法访问m
* m['foo'];
* m.get("foo");
* */
m['bar'] = 5;
/*确定一个键值是否存在*/
trace(m.exists('bar') + " is the value for m.exists('bar')");
trace(m.get('bar') + " is the value for m.get('bar')");
trace(m['bar'] + " is the value for m['bar']");
/*新增 注释 可以用下面这种方法来添加数据*/
var m2 = ['foo' => 4, 'baz' => 6]; // Alternative map syntax
trace(m2 + " is the value for m2");
/*
记住,你可以使用类型推断。Haxe编译器将
在您首次传递设置类型参数的参数时决定变量的类型。 */
var m3 = new Map();
m3.set(6, 'baz'); // m3 is now a Map<Int,String>
trace(m3 + " is the value for m3");
/*
Haxe在haxe.ds模块中有更多常见的数据结构,例如
List,Stack和BalancedTree
*/
////////////////////////////////////////////////// ////////////////
//操作员
///////////////////////////// ////////////////////
trace("***OPERATORS***");
//基本算术
trace((4 + 3) + " is the value for (4 + 3)");
trace((5 - 1) + " is the value for (5 - 1)");
trace((2 * 4) + " is the value for (2 * 4)");
trace((8 / 4) + " is the value for (8 / 3) (division always produces Floats)");
trace((12 % 4) + " is the value for (12 % 4)");
//基本比较
trace((3 == 2) + " is the value for 3 == 2");
trace((3 != 2) + " is the value for 3 != 2");
trace((3 > 2) + " is the value for 3 > 2");
trace((3 < 2) + " is the value for 3 < 2");
trace((3 >= 2) + " is the value for 3 >= 2");
trace((3 <= 2) + " is the value for 3 <= 2");
//按位运算符
/*
~ Unary bitwise complement
<< Signed left shift
>> Signed right shift
>>> Unsigned right shift
& Bitwise AND
^ Bitwise exclusive OR
| Bitwise inclusive OR
*/
// increment
var i = 0;
trace("Increments and decrements");
trace(i++); //i = 1. Post-Incrementation
trace(++i); //i = 2. Pre-Incrementation
trace(i--); //i = 1. Post-Decrementation
trace(--i); //i = 0. Pre-Decrementation
////////////////////////////////////////////////// ////////////////
//控制结构
//////////////////////////// ////////////////////
trace("***CONTROL STRUCTURES***");
// if statements
var j = 10;
if (j == 10){
trace("this is printed");
} else if (j > 10){
trace("not greater than 10, so not printed");
} else {
trace("also not printed.");
}
// there is also a "ternary" if:
(j == 10) ? trace("equals 10") : trace("not equals 10");
/*
最后,还有一种形式的控制结构
在编译时运行:条件编译。
*/
#if neko
trace('hello from neko');
#elseif js
trace('hello from js');
#else
trace('hello from another platform!');
#end
/*
编译后的代码将根据平台目标而有所不同。
由于我们正在为neko(-x或-neko)进行编译,所以我们只得到了neko的
问候语。
*/
trace("循环和迭代");
// while loop
var k = 0;
while(k < 100){
// trace(counter); //将打印出数字0-99
k++;
}
// do-while loop
var l = 0;
do{
trace("do statement always runs at least once");
} while (i > 0);
// 循环
/*
Haxe中没有c-style for循环,因为它们容易出错,而不是必需的。
相反,Haxe有一个使用迭代器的更简单和更安全的版本(更多在以后)。
*/
var m = [1,2,3];
for (val in m){
trace(val + " is the value for val in the m array");
}
//请注意,您可以使用范围
var n = ['foo', 'bar', 'baz'];
for (val in 0...n.length){
trace(val + " is the value for val (an index for m)");
}
trace("Array Comprehensions");
//数组解析使您能够遍历数组
//同时创建过滤器和修改。
var filtered_n = [for (val in n) if (val != "foo") val];
trace(filtered_n + " is the value for filtered_n");
var modified_n = [for (val in n) val += '!'];
trace(modified_n + " is the value for modified_n");
var filtered_and_modified_n = [for (val in n) if (val != "foo") val += "!"];
trace(filtered_and_modified_n + " is the value for filtered_and_modified_n");
////////////////////////////////////////////////// //////////////
// //切换语句(值类型)
//////////////////////// //////////////////////
trace("***SWITCH STATEMENTS (VALUE TYPES)***");
/*
在Haxe中的切换语句非常强大。除了处理
诸如字符串和int之类的基本值之外,它们还可以处理
枚举中的广义代数数据类型(稍后更多的枚举)。
这里有一些基本的价值实例:
*/
/*新增 注释 注意这里 switch语句没有break 要注意这里和其他语言的区别
* 但是我们可以这样写 case 1,2 用逗号把选项分开
* */
var my_dog_name = "fido";
var favorite_thing = "";
switch(my_dog_name){
case "fido" : favorite_thing = "bone";
case "rex" : favorite_thing = "shoe";
case "spot" : favorite_thing = "tennis ball";
default : favorite_thing = "some unknown treat";
// case _ : "some unknown treat"; // same as default
}
//上面的“_”一个“通配符”值,将匹配任何东西。相当于default
race("My dog's name is" + my_dog_name
+ ", and his favorite thing is a: "
+ favorite_thing);
////////////////////////////////////////////////// ////////////////
//表达陈述
//////////////////////////// ////////////////////
trace("***表达声明***");
/* Haxe控制语句非常强大,因为每个语句也是一个表达式*/
/*新增 注释 太强大 先吃一粒定心丸,可能有点颠覆我们的习惯*/
// if statements
var k = if (true){
10;
} else {
20;
}
trace("K equals ", k); //输出10
var other_favorite_thing = switch(my_dog_name) {
case "fido" : "teddy";
case "rex" : "stick";
case "spot" : "football";
default : "some unknown treat";
}
trace("My dog's name is" + my_dog_name
+ ", and his other favorite thing is a: "
+ other_favorite_thing);
////////////////////////////////////////////////// //////////////
// //转换价值类型
/////////////////////////// /////////////////////
trace("***转换类型***");
//您可以很容易地将字符串转换为int。
// string to integer
Std.parseInt("0"); //返回0
Std.parseFloat("0.4"); //返回0.4;
// integer to string
Std.string(0); //返回“0”;
//串联与字符串将自动转换为字符串。
0 + ""; //返回“0”;
true + ""; //返回“true”;
//有关详细信息,请参阅Std中的解析文档。
/*新增 注释 Std 这个类提供了一些常用的数值运算 可以点进入类看看,方法不是很多,且提供了类型判断
* 在as3中 我比较习惯直接 用is 来判断类型,
* 但是在haxe中 is会报错,
* 但是我们可以使用 Std.is(123.1315,Int); 来判断
* */
////////////////////////////////////////////////// ////////////////
//处理类型
/////////////////////////// /////////////////////////////////////
/*
如前所述,Haxe是一种静态类型的语言。总而言之
,静态打字是一件奇妙的事情。
它启用自动完成,可以非常彻底地检查程序的正确性。
另外,Haxe编译器超级快。你可能不会在等待它了。
*无论如何*,有时您只希望编译器会让
某些东西滑动,而不要在有限的情况下抛出类型错误。
为了做到这一点,Haxe有两个单独的关键字。第一个是
“Dynamic”类型:
*/
var dyn: Dynamic = "any type of variable, such as this string";
/*
所有你知道的一个动态变量是
编译器不再担心它是什么类型。它就像一个
通配符变量:你可以传递它,而不是任何变量类型,
你可以分配任何你想要的变量类型。
另一个更极端的选项是“无类型”关键字
*/
untyped {
var x:Int = 'foo';
var y:String = 4;
}
/*
untyped关键字在整个* block *代码上运行,跳过
任何可能需要的类型检查。该关键字应该
非常谨慎地使用,例如在有条件编译的
情况下,类型检查是一种阻碍。
一般来说,跳过类型检查是*不*推荐。使用
枚举,继承或结构类型模型来验证程序的正确性。
只有当您确定所有类型型号都不工作时,您应该使用“动态”或“无类型”。 */
////////////////////////////////////////////////// //////////////
//基础面向对象编程
////////////////////////// ////////////////////
trace("***基于对象的面向对象编程***");
/*
创建一个FooClass的实例。这些类在文件的末尾。 */
var instance = new FooClass(3);
//读取公共变量通常
trace(instance.public_any + " is the value for instance.public_any");
//我们可以读此变量
trace(instance.public_read + " is the value for instance.public_read");
//但不写它
// instance.public_write = 4; //如果取消注释,这将抛出一个错误:
// trace(instance.public_write); //就这样
trace(instance + " is the value for instance"); //调用toString方法
trace(instance.toString() + " is the value for instance.toString()"); // 一样
/*
实例具有“FooClass”类型,而acceptBaseFoo具有
BaseFooClass类型。但是,由于FooClass扩展了BaseFooClass,
所以被接受。
*/
BaseFooClass.acceptBaseFoo(instance);
/*
下面的类有一些更高级的例子,“example()”
方法将在这里运行。
*/
SimpleEnumTest.example();
ComplexEnumTest.example();
TypedefsAndStructuralTypes.example();
UsingExample.example();
}
}
/*
这是主要的LearnHaxe3类的“子类”
*/
class FooClass extends BaseFooClass implements BaseFooInterface{
public var public_any:Int; //公共变量是随时随地访问
public var public_read (default,null): Int; //使用此样式仅启用公共读取
public var public_write (null, default): Int; //或public write
public var property (get, set): Int; //使用此样式来启用getter / setter
//私有变量在类之外是不可用的。
// see @:allow for around around this。
var _private:Int; //如果变量未标记为public,则变量为private
// public
public function new(arg:Int){
super(); //调用父对象的构造函数,因为我们扩展了BaseFooClass
this.public_any= 0;
this._private = arg;
}
// getter for _private
function get_property() : Int {
return _private;
}
// setter for _private
function set_property(val:Int) : Int {
_private = val;
return val;
}
//每当将实例转换为字符串时调用的特殊函数。
public function toString(){
return _private + " with toString() method!";
}
//这个类需要定义这个函数,因为它实现了BaseFooInterface接口。
public function baseFunction(x: Int) : String{
// convert the int to string automatically
return x + " was passed into baseFunction!";
}
}
/*
一个简单的类来扩展
*/
class BaseFooClass {
var base_variable:Int;
public function new(){
base_variable = 4;
}
public static function acceptBaseFoo(b:BaseFooClass){
}
}
/*
一个简单的接口来实现
*/
interface BaseFooInterface{
public function baseFunction(x:Int):String;
}
////////////////////////////////////////////////// //////////////
//枚举和切换语句
////////////////////////// //////////////////////////////////////
/* Haxe中的枚举非常强大。枚举是最简单的形式,它是一个数量有限的类型:*/
enum SimpleEnum {
Foo;
Bar;
Baz;
}
//这是一个使用它的类:
class SimpleEnumTest{
public static function example(){
var e_explicit:SimpleEnum = SimpleEnum.Foo; //可以指定“完整”名称
var e = Foo ; //但推论也会奏效。
switch(e){
case Foo: trace("e was Foo");
case Bar: trace("e was Bar");
case Baz: trace("e was Baz"); // 注释此行以抛出错误。
}
/*
这与字符串上的简单值开关看起来没有什么不同。
但是,如果我们不包括* all *的状态,
编译器会抱怨。您可以通过注释上面的一行来尝试。
您还可以为枚举开关指定默认值:
*/
switch(e){
case Foo: trace("e was Foo again");
default : trace("default works here too");
}
}
}
/*
枚举远远超过简单的状态,
我们也可以枚举 *构造函数*,
但是我们需要一个更复杂的枚举例子
*/
enum ComplexEnum{
IntEnum(i:Int);
MultiEnum(i:Int, j:String, k:Float);
SimpleEnumEnum(s:SimpleEnum);
ComplexEnumEnum(c:ComplexEnum);
}
//注意:上面的枚举可以包括*其他*枚举,包括自己!
class ComplexEnumTest{
public static function example(){
var e1:ComplexEnum = IntEnum(4); //指定枚举参数
/* 现在我们可以打开枚举,并提取它可能有的任何参数。 */
switch(e1){
case IntEnum(x) : trace('$x was the parameter passed to e1');
default: trace("Shouldn't be printed");
}
//这里的另一个参数本身就是枚举枚举枚举?
var e2 = SimpleEnumEnum(Foo);
switch(e2){
case SimpleEnumEnum(s): trace('$s was the parameter passed to e2');
default: trace("Shouldn't be printed");
}
//枚举一路向下
var e3 = ComplexEnumEnum(ComplexEnumEnum(MultiEnum(4, 'hi', 4.3)));
case ComplexEnumEnum(ComplexEnumEnum(MultiEnum(i,j,k))) : {
trace('$i, $j, and $k were passed into this nested monster');
}
default: trace("(“不应打印”");
}
/* 查看“广义代数数据类型”(GADT),了解更多关于为什么这么大的细节。 */
}
}
class TypedefsAndStructuralTypes {
public static function example(){
//这里我们要使用typedef类型,而不是基类型。
var t1:FooString = "some string";
/*
我们可以使用typedef作为“结构类型”。
这些类型由它们的字段结构定义,而不是类继承。
这是一个名为“foo”的String字段的匿名对象:*/
var fooObj = { foo: 'hi' };
/*
记住在我们宣布FooObj typedef的顶部?
由于fooObj与该结构相匹配,
所以我们可以在任何需要“FooObject”的地方使用它。 */
var f = function(fo:FooObject){
trace('$fo was passed in to this function');
}
f(fooObj); //用fooObj调用FooObject签名函数。
/*
请注意,typedef还可以包含可选字段,标有“?”
typedef OptionalFooObj = {
?optionalString: String,
requiredInt: Int
}
*/
/*
Typedef与条件编译工作良好。例如,
我们可以将其包含在文件的顶部:
#if(js)
typedef Surface = js.html.CanvasRenderingContext2D;
#elseif(nme)
typedef Surface = nme.display.Graphics;
#elseif(!flash9)
typedef Surface = flash8.MovieClip;
#elseif(java)
typedef Surface = java.awt.geom.GeneralPath;
#结束
这将给我们一个单一的“表面”类型,以便在所有这些平台上使用。
*/
}
}
class UsingExample {
public static function example() {
/*
“using”import关键字是一种特殊的类导入,
它改变了类中任何静态方法的行为。
在这个文件中,我们将“using”应用于“StringTools”,
它包含了一些用于处理String类型的静态方法。
*/
trace(StringTools.endsWith("foobar", "bar") + " should be true!");
/*
使用“using”导入时,第一个参数类型将使用该
方法进行扩展。这意味着什么?那么,既然“的endsWith”具有第一 “字符串”,
这意味着所有的字符串类型现在有的参数类型“的endsWith”的方法:
*/
trace("foobar".endsWith("bar") + " should be true!");
/*
这种技术可以为某些类型提供很好的表达,
同时限制对单个文件的修改范围。
请注意,String实例在运行时是*不*修改。
新附加的方法不是附加
实例的一部分,编译器仍然生成等效于静态方法的代码。
*/
}
}
相关文章推荐
- haxe 第二期 入门篇 (转载)
- 【转载】8天入门wpf—— 第四天 模板
- Oracle入门学习心得(转载)
- enyo官方开发入门教程翻译一Tutorials之Part2:Onyx and Layout(转载)
- [转载]传智播客_SQL入门
- (转载)MFC入门(五) 作者 zhoujiamurong
- 转载 jQuery Mobile十大常用技巧 (入门基础)
- MySQL入门转载
- 转载一篇优秀的入门实例,说一下自己的理解
- 转载-3分钟了解入门「机器学习」该学习什么?(上)
- 【转载】黑莓开发学习(入门教程)01-前言
- Python Twisted 学习系列2(转载stulife最棒的Twisted入门教程)
- Mac OS 安装以太坊钱包——Geth入门教程(转载)
- 【转载】OPENWRT入门之四------openwrt命令行模式命令及其工具
- [转载]MTK入门教程
- Visual C++ ADO数据库编程入门(转载)
- (转载)VS2010/MFC编程入门之十三(对话框:属性页对话框及相关类的介绍)
- Node入门 (转载)--个人觉得写的不错,赞!
- matlab画图入门篇--各种基本图形绘制的函数与实例【转载】
- java入门的30个基本概念(转载)