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