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