data-type.md 12.1 KB
Newer Older
D
DCloud_LXH 已提交
1 2 3 4
## 数据类型@data-type

### 布尔值(Boolean)

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
5
布尔是简单的基础类型,只有2个值分别是:`true``false`。在全平台没有差异。
DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
6 7 8 9 10

```ts
let a:boolean = true
let b = false
```
D
DCloud_LXH 已提交
11 12 13

### 数字(Number)

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
14
在web中,数字不区分整型和浮点。但在kotlin和swift中,数字需要是一个确定类型,比如Int、Float、Double,没有泛数字。
DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
15

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
16
UTS 在iOS和Android平台上新增了 number 类型,拉齐了web端的实现,方便开发者写全端兼容代码。
DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
17

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
18
number是一个泛数字类型,包括整数或浮点数,包括正数负数。例如: 正整数 `42` 或者 浮点数 `3.14159` 或者 负数 `-1`
D
DCloud_LXH 已提交
19 20

```ts
DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
21
// 以下都是number类型
D
DCloud_LXH 已提交
22
let a:number = 42
DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
23 24 25
let b:number = 3.14159
let c = 42
let d = 3.14159
D
DCloud_LXH 已提交
26 27
```

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
28
注意:UTS中 number 是默认数字类型,书写的字面量如果没有特别指定类型会自动识别为 number。
杜庆泉's avatar
杜庆泉 已提交
29

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
30
除了 number,UTS 在Android和iOS设备上,也可以使用kotlin和swift的专用数字类型:
杜庆泉's avatar
杜庆泉 已提交
31

D
DCloud_LXH 已提交
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
#### Kotlin 特有的数字类型 @Kotlin

- Byte, UByte
- Short, UShort
- Int, UInt
- Long, ULong
- Float
- Double

#### Swift 特有的数字类型 @Swift

- Int, UInt, Int8, UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64
- Float, Float16, Float32, Float64
- Double

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
47 48 49
**特有数字类型的使用场景**

大多数场景下,开发者使用 字面量(即Number类型)就可以满足需要,但是也有需要特有数字类型的场景。
D
DCloud_LXH 已提交
50

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
51 52
1. 在 kotlin 和 swift 中,有些系统API或三方SDK的入参或返回值的类型,强制约定了平台特有数字类型,此时无法使用number。
2. number 作为泛数字,性能还是弱于Int。在普通计算中无法体现出差异,但在千万次运算后,累计会产生毫秒级速度差异。
DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
53 54 55 56

当需要特有数字类型时,UTS中可以直接定义<!--,也可以通过number类型转换为特有数字类型。-->

可以使用下面的方法,虽然可能会被编辑器报语法错误(后续HBuilderX会修复这类误报),但编译到 kotlin 和 swift 时是可用的。
D
DCloud_LXH 已提交
57 58

- 声明特定的平台数字类型
DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
59
 > 目前这些特有数字类型,声明类型时,与 number 不同的是,均为首字母大写
D
DCloud_LXH 已提交
60 61 62 63 64 65 66 67

```ts

let a:Int = 3 //注意 Int 是首字母大写
let b:Int = 4
let c:Double  = a * 1.0 / b
```

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
68 69
* 注意这些特有数字类型不能在web端和小程序端使用,如工程需兼容非App端,要把这些代码放入条件编译中;
* iOS和Android都有的类型,比如Int,编译后可跨2个平台;但如果使用了某平台专有的数字类型,比如swift的Int8,则此代码不能编译到Android,工程如需支持Android,则把这些代码写在条件编译中。
DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
70

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
71
这些特有类型定义后,可以使用kotlin和swift为其提供的各种方法,具体参考kotlin和swift的文档。
DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
72

D
DCloud_LXH 已提交
73 74 75 76 77 78 79 80 81
- 在 kotlin(app-android) 下转换特定的平台数字类型
```ts
let a:Int = 3
a.toFloat() // 转换为 Float 类型,后续也将支持 new Float(a) 方式转换
a.toDouble() // 转换为 Double 类型,后续也将支持 new Double(a) 方式转换
```

- 在 swift(app-ios) 下转换特定的平台数字类型
```ts
lizhongyi_'s avatar
lizhongyi_ 已提交
82 83 84 85 86 87 88
// number转成特定类型
let num = 2
num.toInt() //将number 变量 num 转换为 Int 类型
num.toFloat() //将number 变量 num 转换为 float 类型
num.toInt64() // 将number 变量 num 转换为 Int64 类型

// 特定类型转成其他的特定类型
D
DCloud_LXH 已提交
89 90 91
let a:Int = 3
let b = new Double(a) // 将整型变量 a 转换为 Double 类型
```
DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
92 93 94 95

<!-- #### number和特有数字类型互转 -->

#### 边界情况说明:
D
DCloud_LXH 已提交
96 97 98 99 100 101

- 在不同平台上,数值的范围限制不同,超出限制会导致相应的错误或异常
  * 编译至 JavaScript 平台时,最大值为 1.7976931348623157e+308,最小值为 -1.7976931348623157e+308,超出限制会返回 `Infinity``-Infinity`
  * 编译至 Kotlin 平台时,最大值为 9223372036854775807,最小值为 -9223372036854775808,超出限制会报错:`The value is out of range‌`
  * 编译至 Swift 平台时,最大值 9223372036854775807,最小值 -9223372036854775808,超出限制会报错:`integer literal overflows when stored into Int`

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
102 103 104
#### 更多API
number内置对象还有一些API,[详见](buildin-object-api/number.md)

D
DCloud_LXH 已提交
105 106 107 108 109 110 111 112 113 114 115 116 117
### 字符串(String) @String

字符串是一串表示文本值的字符序列,例如:`"hello world"`

边界情况说明:

- 在不同平台上,字符串的长度限制不同,超出限制会导致相应的错误或异常
  * 编译至 JavaScript 平台时,最大长度取决于 JavaScript 引擎,例如在 V8 中,最大长度为 2^30 - 25,超出限制会报错:`Invalid string length`;在 JSCore 中,最大长度为 2^31 - 1,超出限制会报错:`Out of memory __ERROR`
  * 编译至 Kotlin 平台时,最大长度受系统内存的限制,超出限制会报错:`java.lang.OutOfMemoryError: char[] of length xxx would overflow`
  * 编译至 Swift 平台时,最大长度也受系统内存的限制,超出限制目前没有返回信息。

### 日期(Date)@date

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
118
日期对象表示日期,包括年月日时分秒等各种日期。[详见](buildin-object-api/date.md)
D
DCloud_LXH 已提交
119 120 121 122 123 124

### null

一个表明 null 值的特殊关键字。

有时需定义可为null的字符串,可以在类型描述中使用`|`操作符。
DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
125

D
DCloud_LXH 已提交
126 127 128 129
```ts
let user: string | null
```

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
130 131 132 133 134 135
> 注意:uts 编译为kotlin和swift时不支持 undefined。每个有类型的变量都需要初始化或赋值。

### 数组(Array)

Array,即数组,支持在单个变量名下存储多个元素,并具有执行常见数组操作的成员。

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
136
js和swift的array,是可变长的泛型array。
DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
137

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
138
而在kotlin中,其自带的array是不可变长的,length是固定的。只有arrayList是可变长的。
DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
139

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
140
为了拉齐实现,UTS补充了新的Array,替代kotlin的array。它继承自kotlin的ArrayList,所以可以变长。
DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
141

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
142
如果开发者需要使用原始的kotlin的不可变长的array,需使用 kotlin.array。
杜庆泉's avatar
杜庆泉 已提交
143

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
144 145 146
需要使用 kotlin.array 的场景和特有数字类型一样:
1. 某些系统API或三方原生SDK的入参或返回值强制指定了kotlin的array。
2. uts新增的可动态变长的array,在性能上不如固定length、不可变长的原始kotlin.array。但也只有在巨大量的运算中才能体现出毫秒级的差异。
杜庆泉's avatar
杜庆泉 已提交
147 148 149 150 151

#### 创建一个数组对象

`UTS`中数组的创建有两种方式:

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
152
1. 字面量创建
杜庆泉's avatar
杜庆泉 已提交
153

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
154
```ts
DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
155 156
let a = [1,2,3];//支持
let a = [1,'2',3];//支持
杜庆泉's avatar
杜庆泉 已提交
157 158

// 需要注意的是,字面量创建的数组,不支持出现空的缺省元素
DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
159
let a = [1,,2,3];//不支持
杜庆泉's avatar
杜庆泉 已提交
160 161
```

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
162 163
2. 创建数组对象
```ts
DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
164 165 166 167
let a = new Array(1,2,3);//支持
let a = new Array(1,'2',3);//支持
let a = Array(1,2,3);//支持
let a = Array(1,'2','3');//支持
杜庆泉's avatar
杜庆泉 已提交
168 169 170 171 172 173
```

#### 遍历数组对象

在UTS语言中,推荐使用foreach来实现数组的遍历

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
174
```ts
杜庆泉's avatar
杜庆泉 已提交
175 176 177 178 179 180
const array1: string[] = ['a', 'b', 'c'];
array1.forEach((element:string, index:number) => {
    console.log(array1[index])
});
```

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
181
#### 更多API
杜庆泉's avatar
杜庆泉 已提交
182

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
183
更多Array的API,[详见](https://uniapp.dcloud.net.cn/uts/buildin-object-api/array.html)
杜庆泉's avatar
杜庆泉 已提交
184

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
185
#### kotlin平台的 Array 特性
杜庆泉's avatar
杜庆泉 已提交
186

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
187
<!-- 在kotlin平台上,Array 的具体实现类为: `io.dcloud.uts.UTSArray` -->
杜庆泉's avatar
杜庆泉 已提交
188

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
189
UTS 的 Array 拉齐了各个平台 Array 的功能和定义,可以满足大多数场景需要,但是在涉及与 系统API/三方sdk 交互部分,因为 系统API/三方sdk 是基于 java/kotlin 开发,因此调用时直接使用 UTS 的 Array 会产生类型不一致的错误。
杜庆泉's avatar
杜庆泉 已提交
190

杜庆泉's avatar
杜庆泉 已提交
191
举个例子:
杜庆泉's avatar
杜庆泉 已提交
192

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
193
```ts
杜庆泉's avatar
杜庆泉 已提交
194 195 196
let packageManager = UTSAndroid.getUniActivity()!.getPackageManager();
let intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
杜庆泉's avatar
杜庆泉 已提交
197
// 查询当前设备上安装了几个launcher
杜庆泉's avatar
杜庆泉 已提交
198 199 200
let resolveInfo = packageManager.queryIntentActivities(intent,0);
```

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
201
上面的代码向系统查询了有多少应用可以响应 `launcher`行为 ,返回的 resolveInfo 是一个 `List<ResolveInfo>`
杜庆泉's avatar
杜庆泉 已提交
202

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
203
这种情况下,我们建议的做法是将其先转换为UTS的Array对象再进行其他处理和操作
杜庆泉's avatar
杜庆泉 已提交
204

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
205
```ts
杜庆泉's avatar
杜庆泉 已提交
206 207 208
let launcherList = UTSArray.fromNative(resolveInfo) 
console.log(clothing.length);
```
杜庆泉's avatar
杜庆泉 已提交
209 210 211 212

下面汇总了常用的转换场景和代码:

##### 1 我有一个UTSArray 需要转换为其他类型
杜庆泉's avatar
杜庆泉 已提交
213

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
214
```ts
杜庆泉's avatar
杜庆泉 已提交
215
let utsArr= ["hello","world"]
杜庆泉's avatar
杜庆泉 已提交
216 217

// UTSArray 转换 kotlin.collections.List
杜庆泉's avatar
杜庆泉 已提交
218 219
let kotlinList = utsArr.toKotlinList()

杜庆泉's avatar
杜庆泉 已提交
220 221
// UTSArray 转换 kotlin.Array
let kotlinArray = utsArr.toTypedArray()
杜庆泉's avatar
杜庆泉 已提交
222 223 224

```

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
225
##### 2 我有一个原生类数组类型 需要转成成UTS的Array
杜庆泉's avatar
杜庆泉 已提交
226

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
227
```ts
杜庆泉's avatar
杜庆泉 已提交
228
// kotlin.collections.List 转换 UTSArray
杜庆泉's avatar
杜庆泉 已提交
229
let utsArr= mutableListOf("hello","world")
杜庆泉's avatar
杜庆泉 已提交
230
let kotlinList = UTSArray.fromNative(utsArr) 
杜庆泉's avatar
杜庆泉 已提交
231 232
```

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
233
```ts
杜庆泉's avatar
杜庆泉 已提交
234
// kotlin.Array 转换 UTSArray
杜庆泉's avatar
杜庆泉 已提交
235
let utsArr= arrayOf("hello","world")
杜庆泉's avatar
杜庆泉 已提交
236
let kotlinList = UTSArray.fromNative(utsArr)
杜庆泉's avatar
杜庆泉 已提交
237 238
```

杜庆泉's avatar
杜庆泉 已提交
239

D
DCloud_LXH 已提交
240 241
### Object类型 @object

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
242
对象(object)是指内存中的可以被标识符引用的一块区域,是一种引用类型。包括Array,Date,Map,Set,JSON等。
D
DCloud_LXH 已提交
243 244 245

### any类型 @any

fxy060608's avatar
fxy060608 已提交
246
有时候,我们会想要为那些在编程阶段还不清楚类型的变量指定一个类型。 这些值可能来自于动态的内容,比如来自用户输入或第三方代码库。 这种情况下,我们不希望类型检查器对这些值进行检查而是直接让它们通过编译阶段的检查。 那么我们可以使用 any 类型来标记这些变量:
D
DCloud_LXH 已提交
247 248

```ts
fxy060608's avatar
fxy060608 已提交
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
let notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // okay, definitely a boolean
```

当你只知道一部分数据的类型时,any类型也是有用的。 比如,你有一个数组,它包含了不同的类型的数据:

```ts
let list: any[] = [1, true, "free"];
list[1] = 100;
```

### null类型 @null

uts 的类型系统可以消除来自代码空引用的危险。
DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
264

fxy060608's avatar
fxy060608 已提交
265
许多编程语言中最常见的陷阱之一,就是访问空引用的成员会导致空引用异常。在 Java 中,这等同于 NullPointerException 或简称 NPE。
DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
266

fxy060608's avatar
fxy060608 已提交
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348
在 uts 中,类型系统能够区分一个引用可以容纳 null (可空引用)还是不能容纳(非空引用)。 例如,String 类型的常规变量不能容纳 null:

```ts
let a: string = "abc" // 默认情况下,常规初始化意味着非空
a = null // 编译错误
```

如果要允许为空,可以声明一个变量为可空字符串(写作 string | null):

```ts
let b: string | null = "abc" // 可以设置为空
b = null // ok
```

现在,如果你调用 a 的方法或者访问它的属性,它保证不会导致 NPE,这样你就可以放心地使用:

```ts
const l = a.length
```

但是如果你想访问 b 的同一个属性,那么这是不安全的,并且编译器会报告一个错误:

```ts
const l = b.length // 错误:变量“b”可能为空
```

但是,还是需要访问该属性,对吧?有几种方式可以做到。


#### 在条件中检测 null

首先,你可以显式检测 b 是否为 null:

```ts
if (b != null) {
  console.log(b.length)
}
```

编译器会跟踪所执行检测的信息,并允许你在 if 内部调用 length。

#### 安全的调用

访问可空变量的属性的第二种选择是使用安全调用操作符 ?.:

```ts
const a = "uts"
const b: string | null = null
console.log(b?.length)
console.log(a?.length) // 无需安全调用
```

如果 b 非空,就返回 b.length,否则返回 null,这个表达式的类型是 number | null。

安全调用在链式调用中很有用。例如,一个员工 Bob 可能会(或者不会)分配给一个部门。 可能有另外一个员工是该部门的负责人。获取 Bob 所在部门负责人(如果有的话)的名字, 写作:

```ts
bob?.department?.head?.name
```

如果任意一个属性(环节)为 null,这个链式调用就会返回 null。

#### 空值合并

空值合并运算符(??)是一个逻辑运算符,当左侧的操作数为 null 时,返回其右侧操作数,否则返回左侧操作数。

```ts
const foo = null ?? 'default string';
console.log(foo);
// Expected output: "default string"

const baz = 0 ?? 42;
console.log(baz);
// Expected output: 0
```

#### 非空断言

非空断言运算符(!)将任何值转换为非空类型。可以写 b! ,这会返回一个非空的 b 值(例如:在我们示例中的 String)或者如果 b 为 null,就会抛出一个异常。

```ts
const l = b!.length
D
DCloud_LXH 已提交
349
```