Lite语言——从入门到放弃(二)

github.com/kulics/lite

这次我们来看看 Lite 的函数和结构设计。

函数声明

在 Lite 中,函数也是表达式,必须赋值给变量或常量,声明的格式为

# (->) {} #
function : (->) {
    # 函数逻辑 #
    a = 1 + 1
}

这是一个没有参数也没有返回值的函数。

函数的调用方式和其它大部分语言一样。

# 调用 #
function()

参数

函数的参数定义与定义变量的方式一样,写在函数定义括号箭头前面部分,多个参数用逗号隔开。

# 声明参数 #
processInt : (x int, y int ->) {
    a = x + y
}
# 调用传参 #
processInt(1, 2)

返回值

函数可以输出返回值,这样就可以将处理后的数据返回给调用者去使用。

函数的返回值定义与参数定义相同,不同的是写在函数定义括号箭头后面部分,多个返回值用逗号隔开。

返回语法表示为 <- value。

# 声明返回值 #
getInt : (-> x int, y int) {
    # 返回数据 #
    <- 1, 2
}

a, b = getInt()

函数类型参数

函数本身也存在类型,表示形式与声明的语法一致,只是不需要标识符和函数体。

通过这种方式可以将函数像数据一样传递,这样就可以把部分逻辑的实现交给外部定义。

doSomething : (x int ->) {
    print(x)
}
# do 为函数类型参数 #
useFunction : (do (int->) ->) {
    # 调用外部传入的函数 #
    do(5)
}
# 传递函数 #
useFunction(doSomething)

Lambda 语法

除了传递函数名称,我们也可以直接创建匿名函数作为参数。

useFunction( (x int ->) {
    print(x)
})

当然了,这种方式有点啰嗦。我们既然知道了函数的具体类型,就可以交给编译器去分析声明,用更简单的 Lambda 语法来帮我们声明函数。

# lambda语法为 { id -> expression } #
useFunction( { x -> 
    print(x)
})

嗯,简单多了。

如果这个函数只有一个函数参数,我们甚至可以省略外面的括号。

useFunction{ x -> print(x) }

这样就很棒了是不是?

判断lambda和循环lambda

Lite语言内置了部分常用的lambda语法,在某些场景下可以精简代码设计。
使用判断lambda可以简化一些传值代码,语法结构与判断语法一样,只需要函数标记 ?->

a = ?-> 1 + 1 == 2 {
    5
} _ {
    0
}
b = a ?-> 5 {
    2
} _ {
    3
}

使用循环lambda可以简化一些列表构造,语法结构与循环语法一样,只需要函数标记 @->

arr = i @-> 0..<5 {
    i * 3
}

结构体

在 Lite 中,结构体是将一系列具有相同类型或不同类型的数据构成的数据集合。

结构体的声明格式为

# id := $ {} #
Cat := $ {
    name str
    age int
}

这样就把一个 name 字段和 age 字段包装在一个叫 Cat 的结构中,我们得到了一个新的类型 Cat,它就像 int 和 str 一样是一个可以被构建和传递的新数据类型。

我们不能直接使用 Cat 里面的属性,因为它只是一种类型的声明。我们需要通过实例化,构造出我们需要的独立数据。

# 构造表达式 type{} #
a = Cat{}

结构体内容调用

和其它语言一样,Lite 也通过 . 语法来调用结构体里面的内容。

a.name = "fish"
a.age = 10

结构体函数

函数也是数据,所以结构体也可以直接声明函数,如果需要调用自身,只是需要在前面附带一个参数标志符,表示它自身。

Cat := me $ {
    miao : (->) {
        print(me.name, me.age)
    }
}

这样 Cat 类型就增加了一个 miao 函数,它一样可以被调用。

a.miao()

接口

接口是一种特殊的结构,它的定义形式类似于结构体,但是并不是用来包装数据,而是用来限定结构体必须包含的字段,用来对功能进行抽象,因此里面的内容只需要标志符和类型,不需要初始化。

接口的声明格式为

# id := % {} #
Pet := % {
    getMaster (-> str)
}

这样就声明了一个 Pet 接口,它规定了对应的结构体必须实现 getMaster 函数。

这里的接口也是一个独立的类型,但这个类型只能用来抽象对应的结构体并且使用它们的功能,不能用来构造数据。

因此我们可以这样去使用接口

printMaster : (x Pet ->) {
    print(x.getMaster())
}

就像使用一个结构体一样去使用它的内容。

实现接口

现在我们给 Cat 实现 Pet 接口,只需要在定义后面追加接口定义部分就可以了。

# 实现规定的函数 #
Cat := $ {
    ......
} % Pet {
    getMaster : (-> name str) {
        <- "Kulics"
    }
}

现在我们就可以将 Cat 传递给 Pet 对象使用它了。

a = Cat{}
# 将 Cat 传递给 Pet #
printMaster(a)

结尾

以上是 Lite 函数、结构体和接口的基本语法,对比起其它语言的语法是否更简洁呢?
下一次我们会来看看如何用简洁的语法表达异常处理和异步处理。

    原文作者:kulics
    原文地址: https://segmentfault.com/a/1190000019845352
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞