Hook参考文档,Hook教程,Hook入门,备忘清单

Hook参考文档,Hook教程,Hook入门,备忘清单

入门

介绍

GitHub

在线运行

示例

VSCode 扩展

Hook 看起来是什么样的?

fn factorial(n) {

if (n == 0)

return 1;

return n * factorial(n - 1);

}

Hook 具有类似于 C 的现代语法。

Hello, World

println("Hello, World!");

// Hello, World!

Hook 中的 Hello, World! 程序。

使用 Homebrew 安装

brew tap hook-lang/hook

brew install hook

hook --help

解释器可以通过 Homebrew 获取。

在 Windows 上安装

cd %tmp%

curl -sSLO https://raw.githubusercontent.com/hook-lang/hook/main/scripts/install.bat install

这是你在 Windows 上安装的方法。

类型和值

基本类型

NilBoolNumberStringRangeArrayRecordClosure

基本类型列表。

布尔值

let x = true;

let y = false;

Bool 是布尔类型。所以,它可以是 true 或 false

数字

let x = 0;

let degree = 45; // 整数

let pi = 3.14; // 浮点数

数字可以是整数或浮点数

字符串

let empty = "";

let name = "John";

let message = 'Hello, "John"!';

字符串可以用单引号或双引号表示

区间

let range = 1..5;

println(range);

// 1..5

区间是整数的序列

数组

let fruits = ["apple", "banana", "cherry"];

println(fruits);

// ["apple", "banana", "cherry"]

数组是元素的序列

记录

let p = { x: 5, y: 10 };

println(p);

// {x: 5, y: 10}

记录将字段映射到值

nil 值

let x = nil;

var y;

println(x); // nil

println(y); // nil

nil 表示没有值

假值

if (nil) "true" else "false"; // false

if (false) "true" else "false"; // false

if (true) "true" else "false"; // true

if (0) "true" else "false"; // true

if (1) "true" else "false"; // true

if ("") "true" else "false"; // true

if ([]) "true" else "false"; // true

if ({}) "true" else "false"; // true

只有 nil 和 false 是假值。

语法

注释

// This is a single-line comment.

// And this is

// a multi-line

// comment. ;)

Hook 只支持单行注释。抱歉!

分号

println(1) ; println(2) ; println(3) ;

println(4) ; println(5)

; println(6) ;

; // error: unexpected token `;`

需要使用分号,不允许空语句。

代码块

{

println("Hello");

{

println("World");

}

}

使用代码块定义作用域。

保留字

asbreakcontinuedoelsefalsefnforfromifimportininoutletloopmatchnilreturnstructtraittruevarwhile

有少量保留字。

标识符

var lowercase;

var CAPS_LOCK;

var camelCase;

var PascalCase;

var snake_case;

var _123;

标识符是区分大小写的。

变量

变量

var x; // x contains nil

x = 5; // now, x contains a number

x = "foo"; // a string

println(x);

数值有类型,但变量没有。

不可变变量

let x = 5;

x = 10; // error: cannot assign to immutable variable `x`

let y; // error: unexpected token `;`

不可变变量在声明时必须初始化。

作用域

let x = 5;

{

let y = 15;

println(x); // 10

println(y); // 15

}

println(x); // 5

println(y); // error: variable `y` is used but not defined

当堆分配的变量超出作用域时,会自动释放。

遮蔽

let x = 5;

{

let x = 10; // shadows the outer `x`

println(x); // 10

}

println(x); // 5

变量可以被遮蔽。

运算符和表达式

算术运算

println(5 + 10); // 15

println(5 - 10); // -5

println(5 * 10); // 50

println(5 / 10); // 0.5

println(5 % 10); // 5

println(-5); // -5

基本算术运算符。

比较运算

println(5 == 10); // false

println(5 != 10); // true

println(5 < 10); // true

println(5 > 10); // false

println(5 <= 10); // true

println(5 >= 10); // false

比较运算符。

逻辑运算

println(true && false); // false

println(true || false); // true

println(!true); // false

逻辑运算符。

位运算和移位

println(5 & 10); // 0

println(5 | 10); // 15

println(5 ^ 10); // 15

println(~5); // -6

println(5 << 1); // 10

println(5 >> 1); // 2

位运算和移位运算符。

赋值

var x = 5; // 5

x += 10; // 15

x -= 10; // 5

x *= 10; // 50

x /= 10; // 5

x %= 10; // 5

x &= 10; // 0

x |= 10; // 10

x ^= 5; // 15

x <<= 5; // 480

x >>= 5; // 15

x++; // 16

x--; // 15

赋值运算符。

三元运算符

let x = 5;

let y = if (x > 5) 10 else 20;

println(y);

// 20

在 Hook 中,三元运算符是 if else。

分支

如果

let x = 10;

if (x > 5) {

println("x is greater than 5");

}

// x is greater than 5

if 语句。

如果否则

let x = 11;

if (x == 5) {

println("x is 5");

} else if (x == 10) {

println("x is 10");

} else {

println("x is neither 5 nor 10");

}

// x is neither 5 nor 10

if else 语句。

匹配

let x = 5;

match (x) {

1 => println("one");

2 => println("two");

3 => println("three");

_ => println("other");

}

// other

match 语句。

循环

while

var x = 0;

while (x < 5) {

print(x);

x += 1;

}

// 01234

while 循环。

do while

var x = 0;

do {

print(x);

x += 1;

} while (x < 5);

// 01234

do while 循环。

for

for (var i = 0; i < 5; i++) {

print(i);

}

// 01234

经典的 for 循环。

循环

loop {

println("Press Ctrl+C to stop");

}

无条件的 loop 循环。

中断

var i = 0;

loop {

if (i == 5) break;

print(i);

i += 1;

}

// 01234

使用 break 退出循环。

继续

var i = 0;

loop {

i += 1;

if (i % 2 == 0) continue;

print(i);

if (i == 5) break;

}

// 135

使用 continue 跳过循环体的剩余部分。

字符串

索引字符串

let s = "Hello";

println(s[0]); // H

println(s[1]); // e

println(s[4]); // o

对字符串进行索引返回一个包含1个字符的字符串。

切片字符串

let s = "Hello, World!";

println(s[0..5]); // Hello,

println(s[7..12]); // World!

通过传递一个区间来切片字符串。

连接字符串

let greeting = "Hi" + " there!";

println(greeting);

// Hi there!

使用 + 运算符连接字符串。

数组

索引数组

let a = [1, 2, 3];

println(a[0]); // 1

println(a[1]); // 2

println(a[2]); // 3

对数组进行索引返回一个元素

切片数组

let a = [1, 2, 3, 4];

println(a[0..2]); // [1, 2, 3]

println(a[1..3]); // [2, 3, 4]

println(a[2 .. len(a) - 1]); // [3, 4]

数组从零开始索引

附加元素

var a = [1, 2];

a[] = 3;

println(a);

// [1, 2, 3]

数组是可变的。使用 [] 来附加一个元素

元素赋值

var a = [1, 2, 3];

a[0] = 4;

println(a);

// [4, 2, 3]

更新数组中的元素

连接数组

let a = [1, 2];

let b = [3];

let c = a + b;

println(c);

// [1, 2, 3]

使用 + 运算符来连接数组

数组相减

let a = [1, 2, 2, 3];

let b = [2];

let c = a - b;

println(c);

// [1, 3]

获取两个数组之间的差异。

函数和闭包

函数声明

fn sum(a, b) {

return a + b;

}

println(sum(5, 10));

// 15

函数是一等公民

函数调用

fn greet(name) {

println("Hi, " + name + "!");

}

greet("John", "Doe");

// Hi, John!

参数的数量可以调整

匿名函数

let sum = |a, b| {

return a + b;

};

println(sum(5, 10));

// 15

Hook 也支持匿名函数

闭包

let pi = 3.14;

fn area(r) {

return pi * r * r;

}

println(area(5));

// 78.5

Hook 中的闭包只捕获数值

高阶函数

fn apply(f, x) {

return f(x);

}

fn double(x) {

return x * 2;

}

println(apply(double, 5));

// 10

函数可以作为参数传递或返回

函数的语法糖

fn factorial(n) =>

if (n == 0) 1

else n * factorial(n - 1);

println(factorial(5));

// 120

当函数体是单个表达式时使用 =>

递归

fn fib(n) {

if (n < 2)

return n;

return fib(n - 1) + fib(n - 2);

}

println(fib(10));

// 55

支持递归

内置函数

println(type(5));

// number

println("1" + to_string(2));

// 12

println(len("foo"));

// 3

有许多内置函数

更多内置函数

printprintlntypeis_nilis_boolto_numberto_stringhexlenexitassertpanic

参见:内置函数

结构体

结构体

struct Point {

x, y

}

let p = Point { 5, 10 };

println(p);

// {x: 5, y: 10}

结构体是记录的原型

访问字段

println(p.x); // 5

println(p.y); // 10

使用 . 来访问记录中的字段

字段赋值

p.x = 10;

p.y = 20;

println(p);

// {x: 10, y: 20}

更新记录中字段的值。

解构

解构数组

let a = [1, 2];

let [x, y] = a;

println(x); // 1

println(y); // 2

变量被声明并赋值

解构记录

let p = { x: 5, y: 10 };

let { x } = p;

println(x);

// 5

使用 {} 来解构记录

占位符

let a = [1, 2];

let [x] = a;

let [_, y] = a;

println(x); // 1

println(y); // 2

使用 _ 跳过前导或中间元素。

模块化

导入模块

import math;

println(math.sqrt(25));

// 5

使用 import 将一个模块引入作用域。

导出符号

// my_module.hk

fn useful_fn() {

return "Nothing";

}

return { useful: useful_fn };

返回一个包含要导出符号的记录。

导入本地模块

import "./my_module.hk" as my;

println(my.useful());

// Nothing

指定本地模块的路径。

选择性导入

import { pow, sqrt } from math;

let [ b, c ] = [ 4, 3 ];

let a = sqrt(pow(b, 2) + pow(c, 2));

println(a);

// 5

使用 {} 导入特定的符号。

核心模块

mathosionumbersstringsarraysutf8hashingencodingsocketjsonlists

参见:核心模块

扩展模块

bigintcryptocurlfastcgigeohashleveldbmysqlredisregexsqliteuuidzeromq

这是扩展模块的列表。

io 模块

import { stderr, writeln } from io;

writeln(stderr, "Something went wrong");

// Something went wrong

使用 io 模块将内容输出到 stderr

hashing 模块

import hashing as h;

let d = h.sha256("Hello, world!");

println(hex(d));

// 315f5bdb76d078c43b8ac0064e4a...

hashing 模块提供哈希函数

json 模块

import json;

let j = '{"x": 1, "y": 2}';

let p = json.decode(j);

println(p.x); // 1

let k = json.encode(p);

println(type(k)); // string

使用 json 模块处理 JSON。

错误处理

错误

println(to_int("foo"));

// runtime error: type error: argument #1 is not a convertible string

// at to_int() in

// at main() in example.hk:1

Hook 使用 panic 模式进行错误处理。当出现错误时,解释器会停止运行

语法错误

println("Hello, World!");

// syntax error: unexpected end of file

// at main() in example.hk:1,25

Hook 具有严格的语法

崩溃

panic("Something went wrong");

// panic: Something went wrong

// at main() in example.hk:1

使用内置函数 panic 来引发错误

断言

assert(5 > 10, "5 is not greater than 10");

// assert: 5 is not greater than 10

// at main() in example.hk:1

使用内置函数 assert 来检查条件

返回错误

fn divide(a, b) {

if (b == 0)

return [nil, "division by zero"];

return a / b;

}

if (let [ok, err] = divide(5, 0); ok) {

println(ok);

} else {

println(err);

}

// division by zero

使用一对来返回一个值和一个错误

传递错误

if (let [ok, err] = divide(5, 0); err) {

return [nil, err];

}

传递错误而不处理它

相关推荐

泰国皇家vc多少钱一盒
beat365正规吗

泰国皇家vc多少钱一盒

📅 07-07 👁️ 600
win10怎么设置窗口无边框 win10无边框窗口设置教程
海信43寸300u的电视怎么样?支持2k转4k吗
beat365正规吗

海信43寸300u的电视怎么样?支持2k转4k吗

📅 07-03 👁️ 2160
为什么一直ban卡莉斯塔,这英雄强在哪里
beat365正规吗

为什么一直ban卡莉斯塔,这英雄强在哪里

📅 07-05 👁️ 306
2022世界杯球员名单
365bet体育在线中文

2022世界杯球员名单

📅 07-08 👁️ 4364
3、天刀回流是什么意思
beat365正规吗

3、天刀回流是什么意思

📅 07-12 👁️ 3749