crystal初見,剛開始就翻車?
最近發(fā)現(xiàn)有人回復(fù)我推薦了crystal,閑來無事(其實(shí)很多系列的坑都沒有填)就來簡單的了解一下這語言吧
首先是安裝,目前crystal只有preview版的windows支持,但由于在下本次體驗(yàn)中會(huì)包含圖形內(nèi)容,使用wsl將十分的不方便,所以還是得硬著頭皮裝windows版本的(別問,問就是買不起帶圖形的linux服務(wù)器,自己的linux系統(tǒng)pc因?yàn)槟承﹩栴}寄了)
首先安裝的時(shí)候需要有vs的build tool?一眼LLVM,果不其然還真是:

這里安裝的方式應(yīng)該是很簡單的,首先安裝一下scoop,然后沒git的裝git,沒vs編譯工具的裝vs編譯工具,最后把crystal的源加入scoop,然后scoop install crystal,整體流程和linux系統(tǒng)下的類似

本想著初見就安排使用這里的play命令的,但沒想到

那好吧,我們先來創(chuàng)建一個(gè)項(xiàng)目看一下:



首先看一下項(xiàng)目結(jié)構(gòu)吧:

shared.yml應(yīng)當(dāng)是項(xiàng)目的配置文件,自動(dòng)生成的readme看起來也還行,默認(rèn)的協(xié)議是MIT,默認(rèn)生成的.gitignore如下:
那么我們來編譯一下這個(gè)項(xiàng)目,然后嘗試運(yùn)行一下:

如果不知道發(fā)生了什么的,這里我說一下,msvc的linker錯(cuò)誤,cl是vs編譯工具的命令行程序
大概率是個(gè)windows的獨(dú)占錯(cuò)誤,查找了一番原因,發(fā)現(xiàn)應(yīng)該是cl.exe沒有找到,于是,現(xiàn)在有兩個(gè)選擇擺在我面前,將cl.exe所在目錄加入path,或者用scoop再裝一份vs的編譯工具
打開Visual Studio 2022 Developer PowerShell v17.5.0-pre.1.0可以看到在下是有cl的:



全是鏈接錯(cuò)誤,應(yīng)該是缺少了什么庫,由于這里在下使用的vs 2022的preview版本,可能存在沖突,于是決定在scoop那邊單獨(dú)再裝一個(gè)vs的編譯工具

于是找到之前安裝的編譯工具,添加一個(gè)cli支持應(yīng)該就有cl.exe了(注意在下是有兩個(gè)版本的vs,而vs2022是很多東西的默認(rèn)值,preview版本是在下之前2022還沒有正式版的時(shí)候試用c++20的特性時(shí)裝的,一直延用至今)


那再加三個(gè)呢?

終于

那么再來試試看

經(jīng)過這么久的折騰總算是可以正常編譯了
默認(rèn)項(xiàng)目是一行有效的代碼也沒有的,連hello world都沒有
加上一行
然后再運(yùn)行,

這里我們也不選官方的那兩個(gè)例子,太基礎(chǔ)了,而且http server的文檔在下看了很久還是沒有找到怎么限制請(qǐng)求方法之類的,感覺使用起來有點(diǎn)怪(當(dāng)然可能是在下用習(xí)慣了high-level的http server,如果這個(gè)系列還有后續(xù),我們就后續(xù)再說)
這里我們找到官方的例子https://github.com/crystal-lang/crystal/tree/master/samples/
隨便看一個(gè)例子,就2048吧
首先一個(gè)枚舉用來表示用戶輸入
然后一個(gè)module表示顯示的部分和讀取輸入的部分
繪制沙盤的類
游戲類
最后是注冊(cè)退出事件,并啟動(dòng)游戲
從這個(gè)例子不難看出一些基本語法之類的東西,
module和class是不同的類型(沒錯(cuò),module在crystal中也是一種類型),
靜態(tài)成員變量直接放在類定義里面即可,帶有@的是普通成員變量(以上為個(gè)人看代碼得出的結(jié)論,沒有看官方文檔不知道對(duì)不對(duì)),
Tiles很直觀的表達(dá)了這個(gè)語言的特點(diǎn)之一,靜態(tài)類型,但完全不用寫類型,這應(yīng)該是一個(gè)Enumerable類型,具體是什么類型由于該語言的IDE插件只有語法高亮,我也只能靠猜,
代碼塊都需要end關(guān)鍵字(在下用過的語言當(dāng)中有不少【lua,julia】,和大括號(hào)的各有千秋),
函數(shù)需要def關(guān)鍵字定義,
可用直接{xxx,xxx}返回匿名對(duì)象,
xxxx do ||語法類似閉包(雖然是full OOP,但有閉包還是不錯(cuò)的)
while循環(huán)的語法比較常規(guī)(注意until是執(zhí)行直到xxx,是與while相反的循環(huán),但本質(zhì)是類似的),
構(gòu)造函數(shù)強(qiáng)制要求命名為initialize,但調(diào)用時(shí)使用new(官方說法是這個(gè)new是crystal為你生成的,你只需要定義構(gòu)造函數(shù),管理內(nèi)存的事情由crystal來,該new函數(shù)會(huì)包含開內(nèi)存的代碼)
case when類似switch case(沒用過類C語言的各位知道模式匹配嗎)
運(yùn)算符都比較常規(guī),這里就不專門說明了
函數(shù)返回值就是代碼塊最后的值(這個(gè)算是現(xiàn)代語法里面比較簡便的一條了,雖然只是少數(shù)語言支持了,順帶一提,rust這方面并不出彩,經(jīng)常判斷不出某個(gè)位置的是函數(shù)返回值)
調(diào)用函數(shù)可以用括號(hào),也可以不加括號(hào),此時(shí)參數(shù)在后面用空格隔開(不知道有沒有用過lisp的,雖然語法不完全一樣,但調(diào)用函數(shù)這種前面函數(shù)名后面直接空格加參數(shù)的形式是類似的)
if也是常規(guī)形式(如until是while的反面,unless就是if的反面)
在下找了好久帶?的方法有什么特殊含義,最后發(fā)現(xiàn)只是這個(gè)語言對(duì)于返回bool值的函數(shù)的特殊約定(尷尬)
xxx?的類型應(yīng)該是optional類型
raise用于返回錯(cuò)誤
作為初見,我們就先講到這里,以上的例子是一個(gè)很簡單的控制臺(tái)2048,如果本系列還有第二期,我們會(huì)試著像官方的sdl例子一樣去調(diào)用一個(gè)c庫來試試(計(jì)劃應(yīng)該是raylib)