您的位置:首页 > 其它

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实例在运行时是*不*修改。

           新附加的方法不是附加

           实例的一部分,编译器仍然生成等效于静态方法的代码。      
*/ 

      }

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  haxe