Reason-BasicType

Basic Type

在每個程式語言中都會有一些基本的型態

Reason 屬於強型態的程式語言

這裡介紹的基本型態的變數型態有

  • Boolean
  • 數字
  • 字串
  • 字元

Type

TypeReason 的亮點之一

let 不一定需要宣告 類型

1
let score = 10;

Reason 知道 score 是個 int 型別,透過其值 10 判斷出來。這個稱之為 推斷(inference)

變數宣告(Let binding)

在介紹變數型態之前要先介紹一下如何宣告變數

Reason 中只有使用 let 來宣告變數

1
let a: string = "hello";

雖然在 Reason 中已經宣告,但是在編譯成功後依舊不會看到這個變數

因為當尚未使用到之前是不會產生在結果中

1
2
let a: string = "hello";
Js.log(a);

但是當我們開始使用之後,編譯結果就會出現

Result:

1
2
3
4
5
6
7
8
9
// Generated by BUCKLESCRIPT VERSION 4.0.5, PLEASE EDIT WITH CARE
'use strict';

var a = "hello";

console.log(a);

exports.a = a;
/* Not a pure module */

另外 Reason 是屬於 Block Scope

1
2
3
4
5
if (displayGreeting) {
let message = "Enjoying the docs so far?";
print_endline(message)
};
/*這裡不能呼叫 message*/

也可以這樣處理

1
2
3
4
5
6
7
let message = {
let part1 = "hello";
let part2 = "world";
part1 ++ " " ++ part2
};

Js.log(message);

這樣在外層會無法呼叫 part1, part2

message 會等於 part1 ++ " " ++ part2 的字串組合

編譯後的結果會是

1
2
3
4
5
6
7
'use strict';

var message = "hello world";

console.log(message);

exports.message = message;

而且預設使用 let 宣告的變數都是 Immutable

1
2
let a: string = "hello";
a = "hello world";

這邊會得到一個錯誤訊息

1
2
3
4
5
6
7
8
9
10
11
12
>>>> Start compiling
[1/1] Building src/Demo-HelloWorld.cmj

We've found a bug for you!
/Users/tomas/Documents/iThome/2018/hello-world/src/Demo.re 2:1-17

1 │ let a: string = "hello";
2 │ a = "hello world";

The value a is not an instance variable

>>>> Finish compiling(exit: 1)

但是可以重複使用 let 宣告同一個變數

1
2
3
4
let message = "hello";
Js.log(message); /* Prints "hello" */
let message = "bye";
Js.log(message); /* Prints "bye" */

Type system

雖然 Reason 是屬於強型態,但是也有留一些彈性

若你沒有宣告變數型態的時候,他會自動進行型態推導

1
2
3
4
5
let a = "1";

let b = a ++ "hello";

Js.log(b); /* 1hello */

但是如果使用數字的運算的話

1
2
3
4
5
let a = 1;

let b = a ++ "hello";

Js.log(b); /* Error: */

會得到了一個錯誤

型態錯誤

訊息會相當清楚地告知是哪一個部分錯誤

對於 debug 會相當有利

Boolean

布林值在各個程式語言中佔有相當重要的基本判斷依據

而且在 Javascript 中也是一項令人相當頭痛的變數型態

常常會有很多不小心造成了很多 bug

1
2
3
let testNum = 1;
let isZero: bool = testNum === 0;
Js.log(isZero);

有趣的是編譯結果會是

1
2
3
4
5
6
7
8
9
10
11
12
// Generated by BUCKLESCRIPT VERSION 4.0.5, PLEASE EDIT WITH CARE
'use strict';


var isZero = false;

console.log(isZero);

var testNum = 1;

exports.testNum = testNum;
exports.isZero = isZero;

他並未依據我的順序來做編譯

而是做了一些優化

因為 isZero 比較的是一個常數

所以不論怎樣執行,最後的結果一定是 false

所以他優先宣告了 var isZero = false;

然後在宣告 testNum

基本的布林運算子

  • && - and
  • || - or
  • ! - not
  • <=, >=, <, >
  • == - structural equal
  • === - referential equal
  • != - structural not equal
  • !== - referential equal

運算子中比較有趣的是 =====

1
2
3
4
5
6
7
8
9
let tuple1 = (1, 2, 3);
let tuple2 = (1, 2, 3);
let tuple3 = tuple2;

Js.log(tuple1 == tuple2); /* true */
Js.log(tuple1 == tuple3); /* true */
Js.log(tuple1 === tuple2); /* false */
Js.log(tuple1 === tuple3); /* false */
Js.log(tuple2 === tuple3); /* true */

== 是比較結構是否相等
=== 是比較來源是否相同

數字

1
2
3
4
5
6
7
let zero: int = 0;
let floatNumber: float = 0.1;

Js.log(zero); /* 0 */
Js.log(floatNumber); /* 0.1 */

/* zero === floatNumber will got Error by compiler*/
  • int - 整數
  • float - 浮點數

數字的相加

1
2
3
4
5
let addResult = 1 + 1;
Js.log(addresult);/* 2 */

let floatAddResult = 1.1 + 1.2; /* get compiler Error (WTF) */
Js.log(floatAddResult);

Float 的相加要使用另外一個符號 +.

1
2
3
4
5
let addResult = 1 + 1;
Js.log(addresult);/* 2 */

let floatAddResult = 1.1 +. 1.2; /* 2.3 */
Js.log(floatAddResult);

int 與 float 的比大小

因為 Reason 是強型別的語言

1
2
let twoBiggerThanOne = 2 > 1;
Js.log(twoBiggerThanOne);

intfloat 是不同的型別

無法直接地做比較

所以要先使用 float_of_intint 轉成 float

1
float_of_int(2) > 1.2; /* true */

string

" 使用雙引號宣告的為字串

' 使用單引號宣告的為字元

字元只能有一個字母

1
2
3
4
5
6
7
let name: string = "Tomas";
let yourName: string = "哈囉世界!";
let a: char = 'a';

Js.log(name);
Js.log(a);
Js.log(yourName); /* \xe5\x93\x88\xe5\x9b\x89\xe4\xb8\x96\xe7\x95\x8c! */

在編譯的時候要注意的是如果是中文的話預設是 Unicode

在宣告的時候要先進行處理

而使用 j 除了處理 Unicode 也可以用變數 (類似 ES6 Template)

1
2
3
4
5
6
7
8
9
let name: string = "Tomas";
let yourName: string = {js|哈囉世界!|js};
let world = {js|世界|js};
let helloWorld = {j|你好,$world|j};
let a: char = 'a';

Js.log(name);
Js.log(a);
Js.log(yourName); /* 哈囉世界! */

BuckleScript 編譯前會先尋找 jsj 進行處理

另外字串的相加使用 ++

1
2
3
let hello = "Hello";
let world = "World"
Js.log(hello ++ " " ++ world); /* console.log("Hello World"); */

也可此參考 Reason 的 string API文件

文章目录
  1. 1. Basic Type
    1. 1.1. Type
    2. 1.2. 變數宣告(Let binding)
    3. 1.3. Type system
    4. 1.4. Boolean
      1. 1.4.1. 基本的布林運算子
    5. 1.5. 數字
      1. 1.5.1. 數字的相加
      2. 1.5.2. int 與 float 的比大小
    6. 1.6. string
|