Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
zy009_
unidocs-zh
提交
d56080da
unidocs-zh
项目概览
zy009_
/
unidocs-zh
与 Fork 源项目一致
Fork自
DCloud / unidocs-zh
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
unidocs-zh
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录