原标题:西行漫记之Haxe初探·上篇

1. 简述:haxe是啥?

haxe(读作蛤克思),是以前flash时代诞生的一种的开源跨平台方案。学会了haxe,可以直接用这种类似TypeScript的语法,生成对应的js/php/python/c++等源码,亦可以直接通过脚本编译成指定target(比如exe

1.1 历史背景

Haxe往前,是flash的ActionScript3.0,AS3之前是AS2。AS3用的是ES4的语法,现在的JavaScript,用的是ES6的语法。如果没记错的话,AS2的语法属于JavaScript1.5魔改。

ActionScript3是Adobe出于性能考虑,用了JVM做的实现。相比较,现行的Node.js用的是Chrome的V8。

1.2 Haxe跟TypeScript的区别

其实不太想写这段的,但是还是为了方便,顺手科普一下。TS是JS的超集,HX是AS3的变种,有亲属关系。需要注意的是,Haxe3的语法,相比ES6其实已经落后了,但这并不影响日常使用,因为haxe的生态还是足够stable的。

1.1.1 什么人还在用Haxe?

主要还是这几类:Flash遗老、一部分大龄游戏开发者、以及一部分需要跨平台的游戏开发者。具体可以参考官网的介绍。

1.0 相关的链接

所有本文涉及到的主要参考链接我都先摆在前面,因为这样方便自己检索。

官网:https://haxe.org 答疑聊天室:https://gitter.im/HaxeFoundation/haxe

在线测试hx代码:https://try.haxe.org   API参考:https://api.haxe.org

手册:https://haxe.org/manual/introduction.html  库索引:https://lib.haxe.org

关于宏的参考/1:https://jcward.com/A+Beginners+Guide+To+Hacking+Haxe+Macros

lime命令行:http://lime.software/docs/command-line-tools/basic-commands/

openfl文档:http://www.openfl.org/learn/

以上,暂时就这些。另外,答疑聊天室里面有不少香港的,而且懂的还挺多。

2. hello world

说来惭愧,用haxe写一个hello world其实挺复杂的。

2.1 准备工作

首先你需要安装haxeToolkit,然后,你需要一个编辑器,这里我选vscode。安装完haxe之后,在vscode里面顺便安装haxe的插件。

2.2 hello world的本体

 class Main {
     static function main() {
         trace("Hello, World!");
     }
 }

标准的写法,其实要在main函数前面加一个public。然后把代码写入Main.hx里面,是的,和java一样,haxe也要就文件名同类名保持一致/且类名必须大写开头。而且,Haxe3.4目前,还不支持标识符[identifier]用中文,据说4.0会实现,但我觉得,也不是非常有必要,毕竟还可以用拼音。

2.3 如何运行

这是整个hello world的关键。官方教程[x1]给的用法是通过haxe命令行:

haxe -main Main --interp

这里补充一点,-main参数实际上的意思是,指定提供main函数的class/file。--interp是解释执行的意思,haxeToolkit里面有自带一个虚拟机叫neko(关于这个细节,一开始不用太在意,知道neko是对标lua的轻量级VM就好)。

2.3.1 如何生成exe / 命令行方法

haxe -main Main -cpp build

第一次编译需要点时间。另外应该是需要msbuild的cl或者mingw的gcc来编译的,不过因为自己本机已经有vs2017的build tool了,所以没有另外单独测试过编译环境的依赖问题。编译完成后,命令行运行build\Main.exe即可看到调试输出的结果。

https://haxe.org/manual/target-cpp.html

2.3.2 生成exe的标准策略

标准策略是:用hxml把编译参数单独写出来,然后用 haxe build.hxml 指定到对应hxml即可。

https://haxe.org/manual/compiler-usage-hxml.html

2.3.3 除了转成cpp然后生成exe还有那些输出方式?

个人觉得除了cpp,其他算是常用的还有两种:输出js、输出成neko/然后用nekoVM执行。python的话,倾向于在haxe里面调用python,而不是生成py代码。php和java个人很少能用到,不过也算常见方案。

3. hello world之后该干嘛

这时候你有很多选择,首先取决于你想干嘛。

上图为haxe之上的架构。通常来说,haxe+openfl的关系,很接近C# + WPF。个人觉得haxe还是适合做替代js的活多一点,当然,这方面TypeScript明显更有优势,只是haxe比TS用途更多一点而已。

3.1 我打算用Haxe干嘛

首先是满足日常需求。比如以前拿python写爬虫,今后就换成haxe来做。类似的,也可以替代部分typescript。当然最后还是想在haxe里面直接调用erlang/elixir,以及kdb+/q。其次是用来填坑,当然,小程序用haxe来做,也不是不可以,但是准备工作似乎有点多,不如直接用typescript+taro。其他的坑,erlang这边可以试着用haxe来调用,在一个就是用haxe来实现一个适合编程的输入法。

3.2 我能在haxe方面做哪些有意义的事情

首先是Haxe的中文化。这里的中文化,不是说要汉化Haxe的代码/语法/文档等等,而是根据需要,补充相关的中文使用参考。比如变量命名,我想在haxe的代码内形成一个自己的用词规范,方便以后用来做输入法测试。

4. 写这篇的时候踩了哪些坑?

首先是文档的坑。haxe的API文档,只能搜索class,而不能搜索到class下的function。这时候最好借助第三方搜索工具。比如最开始hello world里面的trace()函数,实际上是在haxe.Log底下的。

其次是宏的使用问题。我写java少,所以看到public static function的时候,很想做个简化,看能否写成psf。后来折腾了一圈下来发现,除非改AST,别无他法。所以最后放弃了,为了偷个小懒而去改AST,没必要。

再次是,因为想重定义现有的库函数名,所以需要用macro做一些预处理工作,于是写了这么一个helper:

import haxe.macro.Expr;
class Util{
  public static macro   function yin(e:Array<Expr>){
    return macro trace($a{e});
  }
}

这里的import Expr,不严格要求可以不写。另外还顺便试了一下在class里面写import,不行,只能写class外面。关于macro的用法,主要参考:https://haxe.org/manual/macro-reification-expression.html  。 这里的$a{}的a,是Array的意思,yin是印的拼音。

最后是,因为macro默认是static function,在继承的时候发现,class的static函数不会被继承。这个我去gitter问了一下,说就目前是这么设计的(估计是考虑到inline到其他target需要优化的缘故)。然后有个德国大佬说,你可以用macro实现这个feature[x2]。我想了想,还是用以前,python pyramid的ZCA架构下的traversal套路比较简单。于是写了一个回溯/类函数的helper-> tryStatic:

 public static function    tryStatic(c,field){
     var gsc=Type.getSuperClass;
     var gcf=Type.getClassFields;
     var rf = Reflect.field;
     var L=[c]; var Lflag=-1;

     while (Lflag!=1){
       var d = L[L.length-1];
       if(d==null) return           rf(L[L.length-2],field);
       else L.push(gsc(d));
       var d2 = gcf(d);
       var Lflag = d2.indexOf(field);
     }
     return rf(L[L.length-1],field);
   }

这个代码发到gitter上的时候,有个香港的dalao说,你这个第2/3/4行的var定义有点多余,会影响inline,进而会影响性能。这个倒是提醒了我,因为这个玩法虽然在py里面没事,但是在cpp里面有没有影响,我还真说不好。不过测试了一下两种不同的策略,生成的js代码实际差不多(感觉不影响js性能)。在一个就是他有提到可读性的问题,说我这个rf()可读性不如原先的。我说这个是用APL用习惯了,代码/变量名越短越好,英文可读性是次要的(有逻辑可读性就行)。

1.3 为什么选择了haxe?

首先,TypeScript没法用很简洁的办法生成stand alone的exe文件,这不适合我用来教学。其次,haxe的语法虽然有点过时,但是基本够用,有些甚至比TS好。比如pattern matching,TS为了兼容ES标准,没有做标准的模式匹配语法,只做了destructure[1][2]。

其次,Haxe的历史包袱小,依赖少,很轻量,用途广。可以说,自己已经打算逐步用haxe代替python了。

5. 下次写点什么?

主要写haxe中文化的基本思路,其他视情况做补充。

尾注:

[2] typescript下的模式匹配:https://pattern-matching-with-typescript.alabor.me

[x2] https://github.com/maitag/peote-view-remaster/blob/master/src/peote/view/Element.hx#L215

Haxe:东游记(上)part1:intro的更多相关文章

  1. Elixir东游记/上:intro/1

    1. 为啥前面还在搞haxe,现在又换到elixir了? erlang本来我就在用,用elixir不过是方便顺手给人科普而已. 2. so,接下来你打算用elixir干嘛? 很简单,写一个简单的解释器 ...

  2. Haxe东游记(上)part1.5:roadmap

    part1.6 = 常用API参考 1.5.7 -> 官方手册目录/总结/中文化 1.8 -> 官方示例/讲解/总结 1.5.6-> haxe整体结构/解析/综述 part2 = 中 ...

  3. 把AspDotNetCoreMvc程序运行在Docker上-part1

    接<基于ASP.Net Core学习Docker技术第一步:在CentOS7安装Docker平台>这个博文,在搭建完成Docker平台之后,可以开始让aspdotnetcore程序运行在d ...

  4. 把AspDotNetCoreMvc程序运行在Docker上-part2:修改容器以及发布镜像

    在上一个part<把AspDotNetCoreMvc程序运行在Docker上-part1>,已经将成功将aspdotnetcore程序运行在两个不同的容器中,目前两个容器的内容完全相同,只 ...

  5. 40 个重要的 HTML5 面试问题及答案

    本文将列出40个重要的HTML 5面试问题及答案,祝各位求职顺利. 目录 介绍 Canvas和SVG图形之间的区别是什么? 如何使用Canvas和SVG绘制矩形? 什么是CSS选择器? 如何使用ID值 ...

  6. 计算几何总结(Part 1~2)

    Preface 对于一个初三连三角函数都不会的蒟蒻来说计算几何简直就是噩梦. 反正都是要学的也TM没办法,那就慢慢一点点学起吧. 计算几何要有正确的板子,不然那种几百行CODE的题写死你. 本蒟蒻的学 ...

  7. HTML5 中 40 个最重要的技术点

    介绍 我是一个ASP.NET MVC的开发者,最近在我找工作的时候被问到很多与HTML5相关的问题和新特性.所以以下40个重要的问题将帮助你复习HTML5相关的知识. 这些问题不是你得到工作的高效解决 ...

  8. ➡️➡️➡️IELTS speaking by simon

    目录 p1 课程概述 p2 speaking part1, intro, warm up introduction questions then 4 questions about one topic ...

  9. 初级字典树查找在 Emoji、关键字检索上的运用 Part-1

    系列索引 Unicode 与 Emoji 字典树 TrieTree 与性能测试 生产实践 前言 通常用户自行修改资料是很常见的需求,我们规定昵称长度在2到10之间.假设用户试图使用表情符号 ‍

随机推荐

  1. Invalid bound statement (not found):xxx错误的可能原因

    1,报错信息 log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvir ...

  2. Hadoop2-HDFS学习笔记之入门(不含YARN及MR的调度功能)

    架构 Hadoop整体由HDFS.YARN.MapReduce三大部分组成,推荐架构参考:https://www.cnblogs.com/zhjh256/p/10573684.html. 注:2.x的 ...

  3. Leaflet获取可视范围内4个顶点

    //地图级别改变时发生 map.on("zoomend", function (e) { var zoom_val = e.target.getZoom(); map_drag() ...

  4. python 包 笔记

    绝对导入和相对导入 我们的最顶级包glance是写给别人用的,然后在glance包内部也会有彼此之间互相导入的需求,这时候就有绝对导入和相对导入两种方式: 绝对导入:以glance作为起始 相对导入: ...

  5. 顺手写一下HTTP协议

    本文目录 一 什么是HTTP协议 二 Http的特点 三 Http报文 回到目录 一 什么是HTTP协议 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写 ...

  6. Redis Index

    Indexes 集群 主从模型 哨兵机制与RAFT算法 实践 单机多实例 开启Sentinel 存储 持久化 RDB 与 AOF 数据结构 内存管理 事务 并发问题 分布式锁 整体图 中间件 Jedi ...

  7. EJB 笔记

    EJB(Enterprise JavaBean)是J2EE服务器端的组件模型,EJB包括会话Bean(Session Bean).实体Bean(Entity Bean).消息驱动Bean(Messag ...

  8. Hive 导入 parquet 格式数据(未完,待续)

    Hive 导入 parquet 格式数据 Parquet 格式文件,查看Schema Parquet 之mapreduce Hive 导入 parquet 格式数据

  9. SharePoint2007使用WebPart加载UserControl

    之前一直做SharePoint2010开发,最近转向了2007开发,感觉两者开发时有很多地方不一样,我现在接触到2007开发项目里面使用Module去加载Application Page,而在Appl ...

  10. CentOS7.5 下搭建SFTP

    CentOS7.5 下搭建SFTP Linux 创建用户组 groupadd sftp 创建用户test useradd -G sftp -s /sbin/nologin test -s 禁止用户ss ...