Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
DCloud
unidocs-zh
提交
d56080da
unidocs-zh
项目概览
DCloud
/
unidocs-zh
通知
3598
Star
108
Fork
921
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
120
列表
看板
标记
里程碑
合并请求
109
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
unidocs-zh
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
120
Issue
120
列表
看板
标记
里程碑
合并请求
109
合并请求
109
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
d56080da
编写于
8月 29, 2023
作者:
D
DCloud_LXH
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
chore: USTJSONObject -> UTSJSONObject
上级
f3c04e78
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
115 addition
and
100 deletion
+115
-100
docs/uts/data-type.md
docs/uts/data-type.md
+113
-98
docs/uts/literal.md
docs/uts/literal.md
+1
-1
docs/uts/operator.md
docs/uts/operator.md
+1
-1
未找到文件。
docs/uts/data-type.md
浏览文件 @
d56080da
# 类型@data-type
强类型语言的特点,是数据类型要求严格。它带来2个好处:
1.
高性能:明确的类型有更大的优化空间,在iOS和Android等
os
上可以节省内存、提高运算速度;web端由于仍编译为js,不具有类型性能优化。
2.
安全的代码:强类型代码编写虽然没有弱类型自由,但类型检查、非空检查...
各种检查可以提升
代码的健壮性。
1.
高性能:明确的类型有更大的优化空间,在iOS和Android等
OS
上可以节省内存、提高运算速度;web端由于仍编译为js,不具有类型性能优化。
2.
安全的代码:强类型代码编写虽然没有弱类型自由,但类型检查、非空检查...
等各种检查可以提高
代码的健壮性。
如果您是js开发者,那么需要一定的学习过程来掌握 UTS 的类型系统。总体原则是你将牺牲一些代码的灵活性,来换取代码的健壮性和高性能。
...
...
@@ -11,8 +11,8 @@
比如
`"abc"`
和
`"你好"`
,都属于字符串string,所有string类型有相同的方法、属性,比如
`.length`
属性获取字符串长度。
UTS 的类型有:
-
基础类型:boolean、number、string、any、null,都是小写
,
前3个typeof返回类型名称,null的typeof是object,any的typeof是运行时值的类型。
-
对象类型:Date、Array、Map、Set、U
STJSONObject,首字母大写,
typeof返回"object",判断准确类型需使用 instanceof
-
基础类型:boolean、number、string、any、null,都是小写
。
前3个typeof返回类型名称,null的typeof是object,any的typeof是运行时值的类型。
-
对象类型:Date、Array、Map、Set、U
TSJSONObject,首字母大写。
typeof返回"object",判断准确类型需使用 instanceof
-
使用 type 来自定义类型
-
特殊类型:function、class、error。
-
平台专有类型:Int、Float、Double、NSString、kotlin.Array...
...
...
@@ -30,7 +30,7 @@ let c:boolean // 定义类型但定义时未赋值
c
=
true
// 后续为变量赋值字面量
```
注意:
**注意:**
-
在js里,true == 1、 false == 0。但在其他强类型语言里,
`1`
和
`0`
是数字类型,无法和布尔类型相比较。
-
注意 boolean 不要简写成 bool
...
...
@@ -112,8 +112,8 @@ number本身的使用很简单,但混入了平台专有数字类型后,会
-
Swift 中 Int 类型是根据平台动态的,在 32 位设备下等同于 Int32, 在64位设备下等同于 Int64。因此建议整型使用 Int, 除非必要,且在保证不会溢出的场景下才使用 Int32、Int64。
-
同样,Swift 中的 UInt 类型也是根据平台动态的,在 32 位设备下等同于 UInt32, 在64位设备下等同于 UInt64。建议使用 UInt,非必要不使用 UInt32、UInt64。
-
Float16 在 iOS14.0 及以上系统上才能使用,使用时注意做系统版本号判断。
[
参考
](
../plugin/uts-uni-api.md#设备
)
-
Float32 是 Float 的
typealise
, 两者等价。
-
Float64 是 Double 的
typealise
, 两者等价。
-
Float32 是 Float 的
类型别名
, 两者等价。
-
Float64 是 Double 的
类型别名
, 两者等价。
#### 专有数字类型的定义方式
...
...
@@ -188,8 +188,8 @@ let a:Int = 1 // 类型为Int
但
`let b:Int = 1/10`
会在 HBuilderX 3.9+起报错,原因见下面第二条规则。
再澄清下规则1:
*
如果定义变量时已经显式声明了类型,和规则1无关
*
如果不是定义变量,和规则1无关
*
如果定义变量时已经显式声明了类型,和规则1无关
*
如果不是定义变量,和规则1无关
也就是如下代码中,
`60`
这个字面量的处理,和规则1无关,不会把这个
`60`
改为number类型
...
...
@@ -218,7 +218,7 @@ test(1/10) // 报错,类型不匹配。需要number而传入Int
这里的
`纯数字字面量的除法`
,指除法表达式中除了数字和运算符,不包括任何其他东西:
-
比如变量:
`let a:Int=1;let b:Int= a/1`
-
比如
被as过
:
`(1 as Int)/10`
-
比如
使用 as 断言
:
`(1 as Int)/10`
以上除法表达式,都不是“纯数字字面量的除法”,都不会被推导为number。
但是这条规则,也会导致一个
**向下兼容问题**
。
...
...
@@ -251,19 +251,19 @@ test((1.0 as Double)/10) //表达式中任意一个数字as一下,都不会走
所有的 number 都支持下列方法进行转换(部分类库API使用java编写,其要求的java类型与下列kotlin类型完全一致,可以直接使用
* toByte(): Byte
* toShort(): Short
* toInt(): Int
* toLong(): Long
* toFloat(): Float
* toDouble(): Double
*
toByte(): Byte
*
toShort(): Short
*
toInt(): Int
*
toLong(): Long
*
toFloat(): Float
*
toDouble(): Double
另外 number 还具备下列函数进行整型的无符号转换,这部分API 在jvm上没有对应的原始数据类型,主要的使用场景是 色值处理等专业计算场景的
`多平台拉齐`
* toUByte(): UByte
* toUShort(): UShort
* toUInt(): UInt
* toULong(): ULong
*
toUByte(): UByte
*
toUShort(): UShort
*
toUInt(): UInt
*
toULong(): ULong
```
ts
let
a
:
number
=
3
...
...
@@ -711,60 +711,62 @@ let kotlinArray = utsArr.toTypedArray()
#### iOS 平台专有数组类型
UTS 中的 Array 对应到 Swift 中就是 Array, 方法是通用的,无需转换。一般情况下,使用 Array 即可。
但是,某些系统或者三方库 API 可能会要求 OC 的 NSArray、NSMutableArray 类型的数组,这个时候就需要进行转换。
>UTS 中的 Array 对应到 Swift 中就是 Array, 方法是通用的,无需转换。一般情况下,使用 Array 即可。
>
>但是,某些系统或者三方库 API 可能会要求 OC 的 NSArray、NSMutableArray 类型的数组,这个时候就需要进行转换。
-
专有数组类型清单
*
NSArray
*
NSMutableArray
-
专有数组类型定义方式
1.
创建 NSArray
NSArray 是 OC 中的不可变数组,顾名思义,数组创建完成之后就不可以再添加或者删除元素。因此,创建 NSArray 对象时就应该完成数组的初始化。
可以通过以下方式创建 NSArray:
```
ts
// 方式一: 创建一个空数组,注意数组创建后就不可改变,不能再添加或者删除元素,应避免使用该方式。
let
a
:
NSArray
=
NSArray
()
// 方式二: 用一个数组创建一个 NSArray, 推荐使用。同样,创建完成后数组不可变。
let
b
:
NSArray
=
NSArray
(
array
=
[
1
,
2
,
3
,
4
])
// 等价于 any[],注意:不是等价于 number[]
// 方式三: 用一个元素定义 NSArray, 不推荐使用
let
c
:
NSArray
=
NSArray
(
object
=
1
)
// 方式四:用不定长元素定义 NSArray, 可以使用
let
d
:
NSArray
=
NSArray
(
objects
=
1
,
"
2
"
,
false
,
"
ok
"
)
```
> NSArray 是 OC 中的不可变数组,顾名思义,数组创建完成之后就不可以再添加或者删除元素。因此,创建 NSArray 对象时就应该完成数组的初始化。可以通过以下方式创建 NSArray:
```ts
// 方式一: 创建一个空数组,注意数组创建后就不可改变,不能再添加或者删除元素,应避免使用该方式。
let a: NSArray = NSArray()
// 方式二: 用一个数组创建一个 NSArray, 推荐使用。同样,创建完成后数组不可变。
let b: NSArray = NSArray(array=[1, 2, 3, 4]) // 等价于 any[],注意:不是等价于 number[]
// 方式三: 用一个元素定义 NSArray, 不推荐使用
let c: NSArray = NSArray(object=1)
// 方式四:用不定长元素定义 NSArray, 可以使用
let d: NSArray = NSArray(objects=1, "2", false, "ok")
```
2.
创建 NSMutableArray
NSMutableArray 是 OC 中的可变数组,其是 NSArray 的子类,可变数组创建后可以增加或者删除元素。NSArray 的所有创建方式也都适用于 NSMutableArray
```
ts
// 方式一: 创建一个空数组,其类型等价于 any[]
let
a
:
NSMutableArray
=
NSMutableArray
()
a
.
add
(
1
)
//添加一个元素
a
.
add
(
"
22
"
)
//添加一个元素
a
.
add
(
false
)
//添加一个元素
a
.
remove
(
1
)
//移除
一个元素
a
.
removeObject
(
at
=
2
)
//移除一个指定下标的
元素
a
.
removeAllObjects
()
//移除全部
元素
a
.
removeLastObject
()
//移除最后一个
元素
// 方式二: 用一个数组创建一个 NSMutableArray, 推荐使用。
let
b
:
NSMutableArray
=
NSMutableArray
(
array
=
[
1
,
2
,
3
,
4
])
// 等价于 any[],注意:不是等价于 number[]
// 方式三: 用一个元素定义 NSMutableArray
let
c
:
NSMutableArray
=
NSMutableArray
(
object
=
1
)
// 方式四:用不定长元素定义 NSMutableArray
let
d
:
NSMutableArray
=
NSMutableArray
(
objects
=
1
,
"
2
"
,
false
,
"
ok
"
)
```
-
NSMutableArray 是 OC 中的可变数组,其是 NSArray 的子类,可变数组创建后可以增加或者删除元素。NSArray 的所有创建方式也都适用于 NSMutableArray
```
ts
// 方式一: 创建一个空数组,其类型等价于 any[]
let
a
:
NSMutableArray
=
NSMutableArray
()
a
.
add
(
1
)
//添加一个元素
a
.
add
(
"
22
"
)
//添加一个元素
a
.
add
(
false
)
//添加
一个元素
a
.
remove
(
1
)
//移除一个
元素
a
.
removeObject
(
at
=
2
)
//移除一个指定下标的
元素
a
.
removeAllObjects
()
//移除全部
元素
a
.
removeLastObject
()
//移除最后一个元素
// 方式二: 用一个数组创建一个 NSMutableArray, 推荐使用。
let
b
:
NSMutableArray
=
NSMutableArray
(
array
=
[
1
,
2
,
3
,
4
])
// 等价于 any[],注意:不是等价于 number[]
// 方式三: 用一个元素定义 NSMutableArray
let
c
:
NSMutableArray
=
NSMutableArray
(
object
=
1
)
// 方式四:用不定长元素定义 NSMutableArray
let
d
:
NSMutableArray
=
NSMutableArray
(
objects
=
1
,
"
2
"
,
false
,
"
ok
"
)
```
-
专有数组类型 转 Array
```
ts
...
...
@@ -797,11 +799,11 @@ let a3: NSMutableArray = NSMutableArray(array= a)
```
-
注意:
+
无论是 NSArray 还是 NSMutableArray 对象创建后都等价于 any[] 类型的数组,此时 Swift 不再有类型推导,可以往可变数组中添加任意类型的非空元素。
+
NSArray 和 NSMutableArray 类型的数组不接受空值 null, 任何情况下不要往这两种类型中注入 null。 否则,在运行时可能会引起应用闪退。
+
Array 类型不能通过 as 方式转换成 NSMutableArray 类型。 但是可以通过 as 方式 转换成 NSArray 类型。
+
Swift 中的 Array 是值类型,其和 TS 中 Array 的一点区别是 可以通 == 判断两个数组是否相等,只要两个数组的类型和元素一样,判等的结果就是 true。
**注意:**
+
无论是 NSArray 还是 NSMutableArray 对象创建后都等价于 any[] 类型的数组,此时 Swift 不再有类型推导,可以往可变数组中添加任意类型的非空元素。
+
NSArray 和 NSMutableArray 类型的数组不接受空值 null, 任何情况下不要往这两种类型中注入 null。 否则,在运行时可能会引起应用闪退。
+
Array 类型不能通过 as 方式转换成 NSMutableArray 类型。 但是可以通过 as 方式 转换成 NSArray 类型。
+
Swift 中的 Array 是值类型,其和 TS 中 Array 的一点区别是 可以通 == 判断两个数组是否相等,只要两个数组的类型和元素一样,判等的结果就是 true。
### 更多API
...
...
@@ -820,7 +822,7 @@ Map 是一种 key value 形式的数据类型。
//定义一个map1,key为string类型,value也是string类型
const
map1
:
Map
<
string
,
string
>
=
new
Map
();
map1
.
set
(
'
key1
'
,
"
abc
"
);
console
.
log
(
map1
.
get
(
'
key1
'
)
//返回 abc
console
.
log
(
map1
.
get
(
'
key1
'
)
)
//返回 abc
//定义一个map1,key为number类型,value是Map类型
const
map2
:
Map
<
number
,
Map
<
string
,
string
>>
=
new
Map
();
...
...
@@ -831,7 +833,9 @@ console.log(map2.get(1)?.get("key1")); //返回 abc。因为名为1的key不一
注意在HBuilderX中console.log一个Map时,返回内容格式如下:
```
sh
[
Object] Map
(
3
)
{
"sex"
:0,
"name"
:
"zhangsan"
,
"age"
:12
}
at pages/index/index.uvue:60
```
开头的[Object]代表其typeof的类型,Map代表它的实际类型,(3)是map的size,{...} 是Map的内容。
...
...
@@ -855,7 +859,7 @@ console.log(map1 instanceof Map); //返回 true
Map对象还有很多API,delete、clear等,
[
详见
](
buildin-object-api/map.md
)
## U
STJSONObject@ust
jsonobject
## U
TSJSONObject@uts
jsonobject
json 在 js 中并非一个独立的类型,对一个 json 对象 typeof 返回的是 object。
...
...
@@ -864,13 +868,13 @@ json 在 js 中用起来很自由,但在强类型语言中,不管kotlin、sw
1.
json对象里的每个属性,都需要定义类型
2.
每个可为空的属性,都需要加
`?.`
,才能安全读写
一般其他强类型语言的用法,是把json数据内容,转为class、interface或type。然后就可以
`.`
了。
一般其他强类型语言的用法,是把json数据内容,转为class、interface或type。然后就可以
使用
`.`
来访问
了。
在 uts 中使用 JSON,有3种方式:
1.
把 json数据转 type,变成一个自定义类型。这不是本章节的内容,详见
[
type
](
#type
)
2.
uts 新增了 UTSJSONObject 对象,可以把 json数据通过字面量赋值 或 JSON.parse()方式,赋值给 uts 内置的 UTSJSONObject 对象。
3.
由于 U
ST
JSONObject有toMap()方法,所以也可以转为Map后使用json数据。
3.
由于 U
TS
JSONObject有toMap()方法,所以也可以转为Map后使用json数据。
UTSJSONObject,是一个类型,可以在变量的冒号后面使用,本节的重点就是介绍UTSJSONObject。
...
...
@@ -934,7 +938,7 @@ let jo2 = {
关于属性名是否需要使用引号包围的规则:
1.
如果是对象字面量赋值,普通属性名称无需使用引号包围,但使用也没问题
2.
如果是对象字面量赋值,且属性名包括
`-`
,则必须两侧加引号包围。
2.
如果是对象字面量赋值,且属性名包括
特殊符号,如:
`-`
,则必须两侧加引号包围。
3.
如果是JSON.parse()方法入参需要的字符串,则属性名必须使用双引号包围(web端规则也是如此)
如果开发者不想搞明白这些细节,可以简单粗暴的都给属性名都加上引号。
...
...
@@ -1011,14 +1015,14 @@ let rect = {
以上述 rect 为例,访问 UTSJSONObject 中的数据,有如下3种方式:
1.
`.`
操作符
1.
`.`
操作符
即
`rect.x`
、
`rect.size.width`
。
这种写法比较简单,和js习惯一致,但在 UTS 中限制较多。它的使用有如下前提:
-
仅限于web和Android,在iOS上swift不支持
`.`
操作符。
-
在Android上也只支持字面量定义json(因为类型可推导)。如果是
`JSON.parse()`
转换的,则不能使用。
2.
[""]
下标属性
2.
`[""]`
下标属性
即
`rect["x"]`
。
这是一种通用的方式,不管通过字面量定义的 UTSJSONObject,还是通过
`JSON.parse()`
,不管是 web、Android、iOS 哪个平台,都可以使用下标方式访问 UTSJSONObject 属性。
...
...
@@ -1066,17 +1070,19 @@ console.log(listArr[0]["title"]); //第一组
多层级下标访问时需要使用 as 转换为 UTSJSONObject
```
ts
var
j
=
{
"
test
"
:{
"
a-b
"
:
1
}}
var
j
=
{
"
test
"
:{
"
a-b
"
:
1
}
}
console
.
log
((
j
[
'
test
'
]
as
UTSJSONObject
)[
'
a-b
'
]);
```
3
.
通过 keyPath 访问 UTSJSONObject 数据
1
.
通过 keyPath 访问 UTSJSONObject 数据
在
`HBuilderX`
3.9.0 之后的版本,UTSJSONObject 提供了另外一种属性访问方式,keyPath。如果你了解 XPath、JSONPath 的话,这个概念类似。
k
ye
path是把
`.`
操作符作为一个字符串传入了UTSJSONObject的一个方法中,比如
`utsObj.getString("address.detailInfo.street")`
k
ey
path是把
`.`
操作符作为一个字符串传入了UTSJSONObject的一个方法中,比如
`utsObj.getString("address.detailInfo.street")`
相对于受限制
`.`
和需要经常as的下标,更推荐使用keyPath方式来操作UTSJSONObject。
...
...
@@ -1246,14 +1252,15 @@ console.log(personList[1].age); //null
### 嵌套
json对象往往有嵌套,即子对象。比如
```
json
{
id
:
1
,
name
:
"zhangsan"
,
age:
18
,
address
:
{
city
:
"beijing"
,
street
:
"dazhongsi road"
"id"
:
1
,
"name"
:
"zhangsan"
,
"age"
:
18
,
"address"
:
{
"city"
:
"beijing"
,
"street"
:
"dazhongsi road"
}
}
```
...
...
@@ -1263,9 +1270,9 @@ json对象往往有嵌套,即子对象。比如
```
ts
type
PersonType
=
{
id
:
number
,
name
:
string
,
name
:
string
,
age
:
number
,
address
:
{
// 错误,这里的address需要单独声明类型
address
:
{
// 错误,这里的address需要单独声明类型
city
:
string
,
street
:
string
}
...
...
@@ -1276,14 +1283,14 @@ type PersonType = {
```
ts
type
PersonAddressType
=
{
city
:
string
,
city
:
string
,
street
:
string
}
type
PersonType
=
{
id
:
number
,
name
:
string
,
name
:
string
,
age
:
number
,
address
:
PersonAddressType
// 把address定义为PersonAddress类型
address
:
PersonAddressType
// 把address定义为PersonAddress类型
}
```
...
...
@@ -1292,14 +1299,14 @@ type PersonType = {
那么嵌套的完整写法例子:
```
ts
type
PersonAddressType
=
{
city
:
string
,
city
:
string
,
street
:
string
}
type
PersonType
=
{
id
:
number
,
name
:
string
,
name
:
string
,
age
:
number
,
address
:
PersonAddressType
// 把address定义为PersonAddress类型
address
:
PersonAddressType
// 把address定义为PersonAddress类型
}
let
person
=
{
id
:
1
,
...
...
@@ -1346,12 +1353,20 @@ console.log(person?.name); // 返回zhangsan。由于person可能为null,pars
注意上述代码中,如果
`let person`
时,想使用冒号定义类型,需要考虑parse失败的情况,要这么写:
```
ts
type
PersonType
=
{
id
:
number
,
name
:
string
}
let
person
:
PersonType
|
null
=
JSON
.
parse
<
PersonType
>
(
jsonString
)
console
.
log
(
person
?.
name
);
// 返回zhangsan
```
或者如果你确保jsonString的值一定是合法的、parse一定可以成功,那么也可以在定义的末尾!号断言,告诉编译器肯定没有问题,那么此后就可以不使用
`?.`
了
```
ts
type
PersonType
=
{
id
:
number
,
name
:
string
}
let
person
:
PersonType
=
JSON
.
parse
<
PersonType
>
(
jsonString
)
!
console
.
log
(
person
.
name
);
// 返回zhangsan
```
...
...
@@ -1373,11 +1388,11 @@ HBuilderX 3.9起内置了一个json转type工具,在`json编辑器`中选择
### 为vue的data中的json定义类型
uvue文件中data中的json数据也涉及类型定义。此时注意:type定义必须放在
`export default {}`
前面。
```
ts
```
html
<script>
type
PersonType
=
{
id
:
number
,
name
:
string
name
:
string
}
export
default
{
data
()
{
...
...
@@ -1405,7 +1420,7 @@ uvue文件中data中的json数据也涉及类型定义。此时注意:type定
// 注意给data定义type,要写在export default的上面
type
PersonType
=
{
id
:
number
,
name
:
string
,
name
:
string
,
age
:
number
,
}
export
default
{
...
...
docs/uts/literal.md
浏览文件 @
d56080da
...
...
@@ -160,7 +160,7 @@ const coffees = ["French Roast", "Colombian", "Kona"]
在JS中,对象字面值是封闭在花括号对
`{}`
中的一个对象的零个或多个“属性名—值”对的(元素)列表。
在uts中,对象字面量赋值给变量,默认会被推导为
[
UTSJSONObject
](
data-type.md#U
ST
JSONObject
)
类型。
在uts中,对象字面量赋值给变量,默认会被推导为
[
UTSJSONObject
](
data-type.md#U
TS
JSONObject
)
类型。
```
ts
// 创建对象
...
...
docs/uts/operator.md
浏览文件 @
d56080da
...
...
@@ -301,7 +301,7 @@ a as string // 正常
1.0
as
number
// 对象字面量也可以as为USTJSONObject或某个type
{
"
id
"
:
1
}
as
U
ST
JSONObject
{
"
id
"
:
1
}
as
U
TS
JSONObject
type
t
=
{
id
:
number
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录