前面几个章节我们学习了鸿蒙的简介、鸿蒙应用的开发环境配置、鸿蒙开发学习路线以及目前华为主推的Stage模型下ArkTS开发范式的项目结构,本章节我们来继续学习ArkTS的基础知识。其实官网上的ArkTS语言开发文档有比较详细的说明,所以这里在官方文档的基础上,结合本人的学习经验总结整理,简要的给大家分享一下ArkTS的基础知识供各位参考学习。ArkTS的基础类型和用法和ts的大致基本相同,与Java也极其相似。
下面我们先来学习ArkTS的声明,ArkTS
通过声明引入变量
、常量
、类型
和函数
。
以关键字let
、var
开头的声明引入变量,该变量在程序执行期间可以具有不同的值。
let name: string = 'yvan'
name = 'my name is yvan'
var name: string = 'yvan1'
以关键字const
开头的声明引入只读常量,该常量只能被赋值一次。对常量重新赋值会造成编译时错误。
const name: string = 'yvan'
由于ArkTS
是一种静态类型语言
,所有数据的类型都必须在编译时确定。
但是,如果一个变量或常量的声明包含了初始值,那么开发者就不需要显式指定其类型。ArkTS
规范中列举了所有允许自动推断类型的场景,初始值类型即属性类型。
let name: string = 'yvan'
let name2 = 'yvan'
ArkTS
提供number
和Number
类型,任何整数和浮点数都可以被赋给此类型的变量,十六进制(0x)、八进制(0o)、二进制(0b)
// 十六进制
let n1 = -0xF1A7
// 八进制
let n2 = 0o777
// 二进制
let n3 = -0b11
let n4 = 3.141592
let n5 = .5
let n6 = 1e10
由true
和false
两个逻辑值组成。
let isDone: boolean = false
代表字符序列,可以使用转义字符来表示字符,单引号
或双引号
括起来都可,$
在其内为模版字面量。
let a = "Success"
let s1 = 'Hello, world!\n'
let s2 = 'this is a string'
// $引入模版字面量
let s3 = `The result is ${a}`
用于指定函数没有返回值。 可以用于泛型类型参数。
// 函数无返回值
test():void{
}
// 泛型类型参数
class Class<T> {
}
let instance: Class <void>
Object
类型是所有引用类型的基类型
。任何值,包括基本类型的值(它们会被自动装箱),都可以直接被赋给Object类型的变量。
array即数组
, 数组的长度由数组中元素的个数来确定。数组中第一个元素的索引为0。
let arr: string[] = ['a', 'b', 'c']
又称枚举类型,是预先定义的一组命名值的值类型,其中命名值又称为枚举常量。 使用枚举常量时必须以枚举类型名称为前缀。
enum Color { Red, Green, Blue }
let c: Color = Color.Red
// 常量表达式可以用于显式设置枚举常量的值。
enum Color { White = 0xFF, Grey = 0x7F, Black = 0x00 }
let c: Color = Color.Black
即联合类型,是由多个类型组合成的引用类型。联合类型包含了变量可能的所有类型。
type UnionType = String | Number | Boolean
let obj : UnionType = Number(111)
obj = "222"
obj = true
// 可以用不同的机制获取联合类型中特定类型的值
if (obj instanceof String) {
let a : String = obj as String
hilog.info(0x0000, "yvan", a.valueOf());
}
Aliases类型为匿名类型(数组、函数、对象字面量或联合类型)提供名称,或为已有类型提供替代名称。
type Matrix = number[][]
type Handler = (s: string, no: number) => string
type Predicate <T> = (x: T) => Boolean
type NullableObject = Object | null
运算符没什么特别之处,有赋值运算符、比较运算符、算术运算符、位运算符、逻辑运算符,基本用法同Java。这里不多赘述,可查阅文档学习。
以下语句也基本同Java的使用,因此可直接看小节总结
。
if语句用于需要根据逻辑条件执行不同语句的场景
if (condition1) {
// 语句1
} else if (condition2) {
// 语句2
} else {
// else语句
}
对于boolean以外的类型,会进行隐式类型转换,null、未赋值、空字符串、0等默认值都为fasle
let s1 = 'Hello'
if (s1) {
console.log(s1) // 打印“Hello”
}
let s2 = 0
if (s2) {
console.log(s2)
}else{
console.log("不成立:"+s2) // 打印“不成立:0”
}
使用switch
语句来执行与switch表达式值匹配的代码块。switch
表达式的类型必须是number
、enum
或string
。label
必须是常量表达式
或枚举常量值
。没有命中走default
,没有写break;
继续往下执行。
switch (expression) {
case label1: // 如果label1匹配,则执行
// 语句1
break; // 可省略
case label2:
case label3: // 如果label2或label3匹配,则执行
// 语句23
break; // 可省略
default:
// 默认语句
}
条件表达式由第一个表达式的布尔值来决定返回其它两个表达式中的哪一个。也可以称作三目运算符。
表达式为true
->执行:前
的结果
表达式为false
->执行:后
的结果
let isValid = Math.random() > 0.5 ? true : false
let message = isValid ? 'Valid' : 'Failed'
for语句
会被重复执行,直到循环退出语句值为false,同Java的For使用
let sum = 0
for (let i = 0; i < 10; i += 2) {
sum += i
}
使用for-of语句
可遍历数组或字符串,类似Java的ForEach语句
let str = 'abcde'
for(let each of str){
console.log("each:"+ch) // 输出:a b c d e
}
只要while括号中的值为true,while语句就会一直执行语句。同Java的While使用。
let n = 0
let x = 0
while (n < 3) {
n++
x += n
}
do-while
也同Java。
let i = 0
do {
i += 1
} while (i < 10)
使用break语句
可以终止循环语句
或switch
let x = 0
while (true) {
x++;
if (x > 5) {
break;
}
}
// 如果break语句后带有标识符,则将控制流转移到该标识符所包含的语句块之外。
let x = 1
label: while (true) {
switch (x) {
case 1:
// statements
break label // 中断while语句
}
}
continue语句
会停止当前循环迭代的执行,并将控制传递给下一个迭代。同Java
let sum = 0
for (let x = 0; x < 100; x++) {
if (x % 2 == 0) {
continue
}
sum += x
}
throw语句
用于抛出异常或错误
try语句
用于捕获和处理异常或错误
finally语句
总会执行的代码
以上三个关键词的使用都同Java
throw new Error('this error')
try {
// 可能发生异常的语句块
} catch (e) {
// 异常处理
} finally {
// 正常或者异常都会执行的代码
}
语句基本同Java的使用,只有一处与Java稍微有区别:
if语句的条件支持非boolean值,对于boolean以外的类型,会进行隐式类型转换,null、undefined、空字符串、0等默认值都为fasle
函数声明引入一个函数,包含其名称
、参数列表
、返回类型
和函数体
。在函数声明中,必须为每个参数标记类型。如果参数为可选参数,那么允许在调用函数时省略该参数。函数的最后一个参数可以是rest参数。
add(x: string, y: string): string {
let z: string = `${x} ${y}`
return z
}
参数名旁使用(?)实现可选参数的功能
function hello(hello:string = 'Hello', name?: string) {
if (name == undefined) {
console.log(hello)
} else {
console.log(hello+", "+name)
}
}
hello(undefined) // 输出:Hello
hello(undefined, 'yvan') // 输出:Hello, yvan
}
剩余参数会被当做个数不限的可选参数。 可以一个都没有,同样也可以有任意个。 可以使用省略号(…) 进行定义:
function add(x: string, ...y: string[]) {
return x + y.join();
}
let result1 = add("a")
let result1 = add("a","b","c","d")
如果可以从函数体内推断出函数返回类型,则可在函数声明中省略标注返回类型。
// 显式指定返回类型
function foo(): string { return 'foo' }
// 推断返回类型为string
function goo() { return 'goo' }
// 无返回类型,可写或不写void
function hi1() { console.log('hi') }
function hi2(): void { console.log('hi') }
函数类型通常用于定义回调
type trigFunc = (x: number) => number // 这是一个函数类型
function do_action(f: trigFunc) {
f(3.141592653589) // 调用函数
}
do_action(Math.sin) // 将函数作为参数传入
函数可以定义为箭头函数,例如:
let sum = (x: number, y: number): number => {
return x + y
}
箭头函数的返回类型可以省略;省略时,返回类型通过函数体推断。
表达式可以指定为箭头函数,使表达更简短,因此以下两种表达方式是等价的:
let sum1 = (x: number, y: number) => { return x + y }
let sum2 = (x: number, y: number) => x + y
箭头函数通常在另一个函数中定义。作为内部函数,它可以访问外部函数中定义的所有变量和函数。
为了捕获上下文,内部函数将其环境组合成闭包,以允许内部函数在自身环境之外的访问。
function f(): () => number {
let count = 0
return (): number => { count++; return count }
}
let z = f()
console.log(z()) // 输出:1
console.log(z()) // 输出:2
在以上示例中,箭头函数闭包捕获count变量。
我们可以通过编写重载,指定函数的不同调用方式。具体方法为,为同一个函数写入多个同名但签名不同的函数头,函数实现紧随其后。
function foo(): void; /* 第一个函数定义 */
function foo(x: string): void; /* 第二个函数定义 */
function foo(x?: string): void { /* 函数实现 */
console.log(x)
}
foo() // OK,使用第一个定义,输出:undefined
foo('aa') // OK,使用第二个定义,输出:aa
不允许重载函数有相同的名字以及参数列表,否则将会编译报错。
ArkTS
声明的变量、常量、类型、函数都跟TypeScript
的大致基本相同,与Java
也极其相似。所以如果是有一定语言基础的小伙伴,学习ArkTS
的语法毫无难度,基本按照官方文档提供的指引学习即可,后面章节我们会继续记录ArkTS
的学习。