crystal初见,刚开始就翻车?
最近发现有人回复我推荐了crystal,闲来无事(其实很多系列的坑都没有填)就来简单的了解一下这语言吧
首先是安装,目前crystal只有preview版的windows支持,但由于在下本次体验中会包含图形内容,使用wsl将十分的不方便,所以还是得硬着头皮装windows版本的(别问,问就是买不起带图形的linux服务器,自己的linux系统pc因为某些问题寄了)
首先安装的时候需要有vs的build tool?一眼LLVM,果不其然还真是:

这里安装的方式应该是很简单的,首先安装一下scoop,然后没git的装git,没vs编译工具的装vs编译工具,最后把crystal的源加入scoop,然后scoop install crystal,整体流程和linux系统下的类似

本想着初见就安排使用这里的play命令的,但没想到

那好吧,我们先来创建一个项目看一下:



首先看一下项目结构吧:

shared.yml应当是项目的配置文件,自动生成的readme看起来也还行,默认的协议是MIT,默认生成的.gitignore如下:
那么我们来编译一下这个项目,然后尝试运行一下:

如果不知道发生了什么的,这里我说一下,msvc的linker错误,cl是vs编译工具的命令行程序
大概率是个windows的独占错误,查找了一番原因,发现应该是cl.exe没有找到,于是,现在有两个选择摆在我面前,将cl.exe所在目录加入path,或者用scoop再装一份vs的编译工具
打开Visual Studio 2022 Developer PowerShell v17.5.0-pre.1.0可以看到在下是有cl的:



全是链接错误,应该是缺少了什么库,由于这里在下使用的vs 2022的preview版本,可能存在冲突,于是决定在scoop那边单独再装一个vs的编译工具

于是找到之前安装的编译工具,添加一个cli支持应该就有cl.exe了(注意在下是有两个版本的vs,而vs2022是很多东西的默认值,preview版本是在下之前2022还没有正式版的时候试用c++20的特性时装的,一直延用至今)


那再加三个呢?

终于

那么再来试试看

经过这么久的折腾总算是可以正常编译了
默认项目是一行有效的代码也没有的,连hello world都没有
加上一行
然后再运行,

这里我们也不选官方的那两个例子,太基础了,而且http server的文档在下看了很久还是没有找到怎么限制请求方法之类的,感觉使用起来有点怪(当然可能是在下用习惯了high-level的http server,如果这个系列还有后续,我们就后续再说)
这里我们找到官方的例子https://github.com/crystal-lang/crystal/tree/master/samples/
随便看一个例子,就2048吧
首先一个枚举用来表示用户输入
然后一个module表示显示的部分和读取输入的部分
绘制沙盘的类
游戏类
最后是注册退出事件,并启动游戏
从这个例子不难看出一些基本语法之类的东西,
module和class是不同的类型(没错,module在crystal中也是一种类型),
静态成员变量直接放在类定义里面即可,带有@的是普通成员变量(以上为个人看代码得出的结论,没有看官方文档不知道对不对),
Tiles很直观的表达了这个语言的特点之一,静态类型,但完全不用写类型,这应该是一个Enumerable类型,具体是什么类型由于该语言的IDE插件只有语法高亮,我也只能靠猜,
代码块都需要end关键字(在下用过的语言当中有不少【lua,julia】,和大括号的各有千秋),
函数需要def关键字定义,
可用直接{xxx,xxx}返回匿名对象,
xxxx do ||语法类似闭包(虽然是full OOP,但有闭包还是不错的)
while循环的语法比较常规(注意until是执行直到xxx,是与while相反的循环,但本质是类似的),
构造函数强制要求命名为initialize,但调用时使用new(官方说法是这个new是crystal为你生成的,你只需要定义构造函数,管理内存的事情由crystal来,该new函数会包含开内存的代码)
case when类似switch case(没用过类C语言的各位知道模式匹配吗)
运算符都比较常规,这里就不专门说明了
函数返回值就是代码块最后的值(这个算是现代语法里面比较简便的一条了,虽然只是少数语言支持了,顺带一提,rust这方面并不出彩,经常判断不出某个位置的是函数返回值)
调用函数可以用括号,也可以不加括号,此时参数在后面用空格隔开(不知道有没有用过lisp的,虽然语法不完全一样,但调用函数这种前面函数名后面直接空格加参数的形式是类似的)
if也是常规形式(如until是while的反面,unless就是if的反面)
在下找了好久带?的方法有什么特殊含义,最后发现只是这个语言对于返回bool值的函数的特殊约定(尴尬)
xxx?的类型应该是optional类型
raise用于返回错误
作为初见,我们就先讲到这里,以上的例子是一个很简单的控制台2048,如果本系列还有第二期,我们会试着像官方的sdl例子一样去调用一个c库来试试(计划应该是raylib)