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.Array,collections.Map,collections.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