• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Sendable使用规则与约束
2<!--Kit: ArkTS-->
3<!--Subsystem: CommonLibrary-->
4<!--Owner: @lijiamin2025-->
5<!--Designer: @weng-changcheng-->
6<!--Tester: @kirl75; @zsw_zhushiwei-->
7<!--Adviser: @ge-yafang-->
8
9## 继承规则
10
11### Sendable类必须继承自Sendable类
12
13Sendable对象的布局和原型链不可变,而非Sendable对象可以通过特殊方式修改布局。因此,不允许互相继承。这里的类不包含变量,Sendable类不能继承自变量。
14
15**正例:**
16
17```ts
18@Sendable
19class A {
20  constructor() {
21  }
22}
23
24@Sendable
25class B extends A {
26  constructor() {
27    super()
28  }
29}
30```
31<!-- @[counter_example](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/ConcurrentThreadCommunication/InterThreadCommunicationObjects/SendableObject/RulesAndRestrictions/inheritonly/src/main/ets/pages/Index.ets) -->
32
33**反例:**
34
35```ts
36class A {
37  constructor() {
38  }
39}
40
41@Sendable
42class B extends A { // A不是sendable class,B不能继承它,编译报错
43  constructor() {
44    super()
45  }
46}
47```
48
49
50### 非Sendable类必须继承自非Sendable类
51
52Sendable对象的布局和原型链不可变,而非Sendable对象可以通过特殊方式修改布局,因此不允许互相继承。
53
54**正例:**
55
56```ts
57class A {
58  constructor() {
59  }
60}
61
62class B extends A {
63  constructor() {
64    super()
65  }
66}
67```
68<!-- @[counter_example](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/ConcurrentThreadCommunication/InterThreadCommunicationObjects/SendableObject/RulesAndRestrictions/inheritedfromnon/src/main/ets/pages/Index.ets) -->
69
70**反例:**
71
72```ts
73@Sendable
74class A {
75  constructor() {
76  }
77}
78
79class B extends A { // A是sendable class,B不能继承它,编译报错
80  constructor() {
81    super()
82  }
83}
84```
85
86## 接口实现规则
87
88### 非Sendable类禁止实现Sendable接口
89
90非Sendable类实现Sendable接口时,可能被误认为是Sendable类,导致错误使用。
91
92**正例:**
93
94```ts
95interface I {};
96
97class B implements I {};
98```
99<!-- @[counter_example_achieve_non](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/ConcurrentThreadCommunication/InterThreadCommunicationObjects/SendableObject/RulesAndRestrictions/achievenon/src/main/ets/pages/Index.ets) -->
100
101**反例:**
102
103```ts
104import { lang } from '@kit.ArkTS';
105
106type ISendable = lang.ISendable;
107
108interface I extends ISendable {};
109
110class B implements I {};  // I是sendable interface,B不能实现,编译报错
111```
112
113## Sendable类/接口成员变量规则
114
115### 必须是Sendable支持的数据类型
116
117Sendable数据不得持有非Sendable数据,因此Sendable类或接口的成员变量必须是[Sendable支持的数据类型](arkts-sendable.md#sendable支持的数据类型)。
118
119**正例:**
120
121```ts
122@Sendable
123class A {
124  constructor() {
125  }
126  a: number = 0;
127}
128```
129<!-- @[counter_example](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/ConcurrentThreadCommunication/InterThreadCommunicationObjects/SendableObject/RulesAndRestrictions/variablesupport/src/main/ets/pages/Index.ets) -->
130
131**反例:**
132
133```ts
134@Sendable
135class A {
136  constructor() {
137  }
138  b: Array<number> = [1, 2, 3] // 编译报错,需使用collections.Array
139}
140```
141
142
143### 不支持使用!断言
144
145Sendable对象的成员属性必须赋初值,而“!”修饰的变量可以不赋初值,因此不支持使用“!”。
146
147**正例:**
148
149```ts
150@Sendable
151class A {
152  constructor() {
153  }
154  a: number = 0;
155}
156```
157<!-- @[counter_example](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/ConcurrentThreadCommunication/InterThreadCommunicationObjects/SendableObject/RulesAndRestrictions/variablenotsupported/src/main/ets/pages/Index.ets) -->
158
159**反例:**
160
161```ts
162@Sendable
163class A {
164  constructor() {
165  }
166  a!: number; // 编译报错,不支持使用“!”
167}
168```
169
170
171### 不支持使用计算属性名
172
173Sendable对象的布局不可更改,因为计算属性无法静态确定对象布局,所以不支持。
174
175**正例:**
176
177```ts
178@Sendable
179class A {
180    num1: number = 1;
181    num2: number = 2;
182    add(): number {
183      return this.num1 + this.num2;
184    }
185}
186```
187<!-- @[counter_example](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/ConcurrentThreadCommunication/InterThreadCommunicationObjects/SendableObject/RulesAndRestrictions/nocalculationsupport/src/main/ets/pages/Index.ets) -->
188
189**反例:**
190
191```ts
192enum B {
193    b1 = "bbb"
194}
195@Sendable
196class A {
197    ["aaa"]: number = 1; // 编译报错,不支持["aaa"]
198    [B.b1]: number = 2; // 编译报错,不支持[B.b1]
199}
200```
201
202## 泛型规则
203
204### 泛型类中的Sendable类、SendableLruCache、collections.Arraycollections.Mapcollections.Set的模板类型必须是Sendable类型
205
206Sendable数据不能持有非Sendable数据,因此泛型类中的Sendable数据的模版类型必须是Sendable类型。
207
208**正例:**
209
210```ts
211import { collections } from '@kit.ArkTS';
212
213try {
214  let arr1: collections.Array<number> = new collections.Array<number>();
215  let num: number = 1;
216  arr1.push(num);
217} catch (e) {
218  console.error(`taskpool execute: Code: ${e.code}, message: ${e.message}`);
219}
220```
221<!-- @[counter_example](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/ConcurrentThreadCommunication/InterThreadCommunicationObjects/SendableObject/RulesAndRestrictions/templatetype/src/main/ets/pages/Index.ets) -->
222
223**反例:**
224
225```ts
226import { collections } from '@kit.ArkTS';
227
228try {
229  let arr1: collections.Array<Array<number>> = new collections.Array<Array<number>>(); // 编译报错,模板类型必须是Sendable类型
230  let arr2: Array<number> = new Array<number>();
231  arr2.push(1);
232  arr1.push(arr2);
233} catch (e) {
234  console.error(`taskpool execute: Code: ${e.code}, message: ${e.message}`);
235}
236```
237
238
239## 上下文访问规则
240
241### Sendable类的内部不允许使用当前模块内上下文环境中定义的变量
242
243由于Sendable对象在不同并发实例间的上下文环境不同,属于单个虚拟机实例,如果直接访问会有非预期行为。不支持Sendable对象使用当前模块内上下文环境中定义的变量,违反此规则会在编译阶段报错。
244
245> **说明:**
246>
247> 从API version 12开始,Sendable class的内部支持使用top level的Sendable class对象。
248
249**正例:**
250
251```ts
252import { lang } from '@kit.ArkTS';
253
254type ISendable = lang.ISendable;
255
256interface I extends ISendable {}
257
258@Sendable
259class B implements I {
260  static o: number = 1;
261  static bar(): B {
262    return new B();
263  }
264}
265
266@Sendable
267class C {
268  v: I = new B();
269  u: number = B.o;
270
271  foo() {
272    return B.bar();
273  }
274}
275```
276<!-- @[counter_example](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/ConcurrentThreadCommunication/InterThreadCommunicationObjects/SendableObject/RulesAndRestrictions/notallowedInside/src/main/ets/pages/Index.ets) -->
277
278**反例:**
279
280```ts
281import { lang } from '@kit.ArkTS';
282
283type ISendable = lang.ISendable;
284
285interface I extends ISendable {}
286
287@Sendable
288class B implements I {}
289
290function bar(): B {
291  return new B();
292}
293
294let b = new B();
295
296{
297  @Sendable
298  class A implements I {}
299
300  @Sendable
301  class C {
302    u: I = bar(); // bar不是sendable class对象,编译报错
303    v: I = new A(); // A不是定义在top level中,编译报错
304
305    foo() {
306      return b; // b不是sendable class对象,而是sendable class的实例,编译报错
307    }
308  }
309}
310```
311
312## \@Sendable装饰器使用规则
313
314### \@Sendable装饰器仅支持修饰类和函数
315
316当前仅支持修饰类和函数。
317
318**正例:**
319
320```ts
321@Sendable
322type SendableFuncType = () => void;
323
324@Sendable
325class C {}
326
327@Sendable
328function SendableFunc() {
329  console.info("Sendable func");
330}
331```
332<!-- @[counter_example_only_support](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/ConcurrentThreadCommunication/InterThreadCommunicationObjects/SendableObject/RulesAndRestrictions/achievenon/src/main/ets/pages/Index.ets) -->
333
334**反例:**
335
336```ts
337@Sendable
338type A = number; // 编译报错
339
340@Sendable
341type D = C; // 编译报错
342```
343
344### Sendable类和Sendable函数禁止使用除\@Sendable外的装饰器
345
346在ts文件中定义类装饰器时,可能会改变类的结构,进而引发运行时错误。
347
348**正例:**
349
350```ts
351@Sendable
352class A {
353  num: number = 1;
354}
355```
356<!-- @[counter_example](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/ConcurrentThreadCommunication/InterThreadCommunicationObjects/SendableObject/RulesAndRestrictions/cannotbeused/src/main/ets/pages/Index.ets) -->
357
358**反例:**
359
360```ts
361@Sendable
362@Observed // 编译报错
363class C {
364  num: number = 1;
365}
366```
367
368## 初始化规则
369
370### 禁止使用对象字面量/数组字面量初始化Sendable对象
371
372对象字面量和数组字面量不是Sendable类型。Sendable类型必须通过Sendable类型的new表达式创建。
373
374**正例:**
375
376```ts
377import { collections } from '@kit.ArkTS';
378
379let arr1: collections.Array<number> = new collections.Array<number>(1, 2, 3); // 是Sendable类型
380```
381<!-- @[counter_example](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/ConcurrentThreadCommunication/InterThreadCommunicationObjects/SendableObject/RulesAndRestrictions/objectliterals/src/main/ets/pages/Index.ets) -->
382
383**反例:**
384
385```ts
386import { collections } from '@kit.ArkTS';
387
388let arr2: collections.Array<number> = [1, 2, 3]; // 不是Sendable类型,编译报错
389let arr3: number[] = [1, 2, 3]; // 不是Sendable类型,正例,不报错
390let arr4: number[] = new collections.Array<number>(1, 2, 3); // 编译报错
391```
392
393## 类型转换规则
394
395### 禁止非Sendable类型强制转换为Sendable
396
397除了Object类型,非Sendable类型不能强转成Sendable类型。非Sendable类型通过as强转成Sendable类型后,实际数据仍为非Sendable类型,会导致错误使用。Sendable类型在不违反Sendable规则的前提下,需要和非Sendable类型行为兼容,因此Sendable类型可以通过as强转成非Sendable类型。
398
399**正例:**
400
401```ts
402class A {
403  state: number = 0;
404}
405
406@Sendable
407class SendableA {
408  state: number = 0;
409}
410
411let a1: A = new SendableA() as A;
412```
413<!-- @[counter_example](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/ConcurrentThreadCommunication/InterThreadCommunicationObjects/SendableObject/RulesAndRestrictions/typecannot/src/main/ets/pages/Index.ets) -->
414
415**反例:**
416
417```ts
418class A {
419  state: number = 0;
420}
421
422@Sendable
423class SendableA {
424  state: number = 0;
425}
426
427let a2: SendableA = new A() as SendableA; // 编译报错
428```
429
430## 函数规则
431
432### 箭头函数不可标记为Sendable
433
434箭头函数不支持\@Sendable装饰器,因此它是非Sendable函数,因此不支持共享。
435
436**正例:**
437
438```ts
439@Sendable
440type SendableFuncType = () => void;
441
442@Sendable
443function SendableFunc() {
444  console.info("Sendable func");
445}
446
447@Sendable
448class SendableClass {
449  constructor(f: SendableFuncType) {
450    this.func = f;
451  }
452  func: SendableFuncType;
453}
454
455let sendableClass = new SendableClass(SendableFunc);
456```
457<!-- @[counter_example](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/ArkTsConcurrent/ConcurrentThreadCommunication/InterThreadCommunicationObjects/SendableObject/RulesAndRestrictions/arrowfunctions/src/main/ets/pages/Index.ets) -->
458
459**反例:**
460
461```ts
462@Sendable
463type SendableFuncType = () => void;
464let func: SendableFuncType = () => {}; // 编译报错
465
466@Sendable
467class SendableClass {
468  func: SendableFuncType = () => {}; // 编译报错
469}
470```
471
472## 与TS/JS交互的规则
473
474### ArkTS通用规则(目前只针对Sendable对象)
475
476| 规则 |
477| -------- |
478| Sendable对象传入TS/JS的接口中,禁止操作其对象布局(增、删属性,改变属性类型)。 |
479| Sendable对象设置到TS/JS的对象上,TS中获取到Sendable对象后,禁止操作其对象布局(增、删属性,改变属性类型)。 |
480| Sendable对象放入TS/JS的容器中,TS中获取到Sendable对象后,禁止操作其对象布局(增、删属性,改变属性类型)。 |
481
482> **说明:**
483>
484> 改变属性类型不包括Sendable对象类型的改变,例如从Sendable class A变为Sendable class B。
485
486
487### NAPI规则(目前只针对Sendable对象)
488
489NAPI相关接口请参考[Sendable相关的NAPI接口](../napi/use-napi-about-extension.md#sendable相关),具体使用请参考[Native与Sendable ArkTS对象绑定](../napi/use-sendable-napi.md)。
490
491| 规则 |
492| -------- |
493| 禁止删除属性。不能使用napi_delete_property接口。 |
494| 禁止新增属性。不能使用napi_set_property、napi_set_named_property、napi_define_properties接口。 |
495| 禁止修改属性类型。不能使用napi_set_property、napi_set_named_property、napi_define_properties接口。 |
496| 不支持Symbol相关接口和类型。不能使用napi_create_symbol、napi_is_symbol_object、napi_symbol接口。 |
497
498
499## 与UI交互的规则
500
501Sendable数据需要与[makeObserved](../ui/state-management/arkts-new-makeObserved.md)配合使用,才可以观察Sendable对象的数据变化,具体使用请参考[makeObserved和@Sendable装饰的class配合文档](../ui/state-management/arkts-new-makeObserved.md#makeobserved和sendable装饰的class配合使用)。
502
503
504## 在HAR包中的使用规则
505
506HAR中使用Sendable时,需启用编译生成TS文件的配置。具体使用请参考[编译生成TS文件](../quick-start/har-package.md#编译生成ts文件)。
507