1# ArkCompiler子系统变更说明 2 3## cl.arkcompiler.1 Sendable容器TypedArray提供的map方法的回调函数声明变更 4 5**访问级别** 6 7公开接口 8 9**变更原因** 10 11Sendable容器TypedArray提供map方法。该方法对TypedArray中的每个元素进行某种操作或转换(通过callbackFn的返回值),并返回一个新的TypedArray,其中包含经过映射函数处理后的结果。 12 13以Uint8Array为例,变更前,map函数的callbackFn声明无返回值,导致转换后的数据丢失,引起开发者使用上的困惑。 14- map方法的回调函数声明为`map(callbackFn: TypedArrayForEachCallback<number, Uint8Array>): Uint8Array;` 15- 而TypedArrayForEachCallback 的定义为无返回值的:`type TypedArrayForEachCallback<ElementType, ArrayType> = (value: ElementType, index: number, array: ArrayType) => void;` 16 17**变更影响** 18 19此变更为不兼容变更。 20 21**变更前** 22 23- 情况一: map函数中的callbackFn无返回值,能通过编译,但是无法实现map功能 24- 情况二: map函数中的callbackFn有返回值,但是返回类型不是number,能通过编译,能实现map功能 25- 情况三: map函数中的callbackFn有返回值,且返回类型是number,能通过编译,能实现map功能 26 27``` 28let arr = [1, 2, 3, 4, 5]; 29 30// 创建一个Uint8Array 31let uint8: collections.Uint8Array = new collections.Uint8Array(arr); 32 33// 情况一:不能完成map功能:callbackFn无返回值,map函数返回新的collections.Uint8Array 34let zeroMappedArray: collections.Uint8Array = uint8.map((value: number) => {}); // 能通过编译 35console.info('' + zeroMappedArray); // 输出: collections.Uint8Array [0, 0, 0, 0, 0] 36 37// 情况二:能完成map功能:callbackFn返回map后的元素值,但类型为string,map函数返回新的collections.Uint8Array 38let wrongTypeMapped: collections.Uint8Array = uint8.map((value: number) => value + "1"); // 能通过编译 39console.info('' + wrongTypeMapped); // 输出: collections.Uint8Array [11, 21, 31, 41, 51] 40 41// 情况三:能完成map功能:callbackFn返回map后的元素值,map函数返回新的collections.Uint8Array 42let normalMapped: collections.Uint8Array = uint8.map((value: number) => value * 2); // 能通过编译 43console.info('' + normalMapped); // 输出: collections.Uint8Array [2, 4, 6, 8, 10] 44``` 45 46**变更后** 47 48- 情况一: map函数中的callbackFn无返回值,不能通过编译(不兼容变更) 49- 情况二: map函数中的callbackFn有返回值,但是返回类型不是number,不能通过编译(不兼容变更) 50- 情况三: map函数中的callbackFn有返回值,且返回类型是number,能通过编译,能实现map功能(兼容) 51 52 53``` 54let arr = [1, 2, 3, 4, 5]; 55 56// 创建一个Uint8Array 57let uint8: collections.Uint8Array = new collections.Uint8Array(arr); 58 59// 情况一:不能完成map功能:callbackFn无返回值,map函数返回新的collections.Uint8Array 60let zeroMappedArray: collections.Uint8Array = uint8.map((value: number) => {}); // 不兼容变更:不能通过编译 61 62// 情况二:能完成map功能:callbackFn返回map后的元素值,但类型为string,map函数返回新的collections.Uint8Array 63let wrongTypeMapped: collections.Uint8Array = uint8.map((value: number) => value + "1"); // 不兼容变更:不能通过编译 64 65// 情况三:能完成map功能:callbackFn返回map后的元素值,map函数返回新的collections.Uint8Array 66let normalMapped: collections.Uint8Array = uint8.map((value: number) => value * 2); // 能通过编译 67console.info('' + normalMapped); // 输出: collections.Uint8Array [2, 4, 6, 8, 10] 68``` 69 70**起始API Level** 71 72API12 73 74**变更发生版本** 75 76从OpenHarmony SDK 5.0.0.31 版本开始。 77 78**变更的接口/组件** 79 80/interface/sdk-js/arkts/@arkts.collections.d.ets中TypedArray(包括Int8Array/Uint8Array/Int16Array/Uint16Array/Int32Array/Uint32Array)的map接口 81 82**适配指导** 83 84- 举例:上述场景二的例子,可以做如下修改: 85``` 86let wrongTypeMapped: collections.Uint8Array = uint8.map((value: number) => parseInt(value + "1")); // 通过parseInt进行字符串到number的转换 87``` 88 89- 详细说明参见:接口使用的示例代码: 90[ArkTS容器集 - TypedArray](../../../application-dev/reference/apis-arkts/js-apis-arkts-collections.md#collectionstypedarray) 91 92## cl.arkcompiler.2 ArkTS Sendable语法规则编译检查完善 93 94**访问级别** 95 96其他 97 98**变更原因** 99 100Sendable对象需要遵循一定[使用规则](../../..//application-dev/arkts-utils/arkts-sendable.md#sendable使用规则),在Sendable泛型类的部分语法中,编译器没有对应的检查,导致这些语法下的Sendable对象用在并发场景中运行异常但是没有无编译时错误。在本次版本更新中,我们修复了这些场景下Sendable约束的编译时检查,将运行时异常提前到编译时。旨在通过编译时错误,帮助开发者更早发现Sendable使用约束,减少运行时定位成本。 101 102**变更影响** 103 104此变更为不兼容变更。 105 106 107变更前:当Sendable泛型类用作类型标注时,类型形参可以使用Non-sendable类型,DevEco编辑界面没有错误提示,编译没有报错。 108 109变更后:当Sendable泛型类用作类型标注时,类型形参不可以使用Non-sendable类型,DevEco编辑界面有错误提示,编译有报错。 110 111对于使用Sendable泛型类进行声明,但是被赋值为Non-sendable对象的变量/参数/返回值,如果它们被用在并发实例共享的场景中,变更前会有运行时异常,变更后错误提前至编译期。如果它们被当作普通对象使用时,变更前运行时不报错,变更后编译器新增报错。 112 113 114具体场景示例: 115 116Sendable泛型类约束 117 118场景一:当Sendable对象被用在多线程共享时,影响:运行时异常提前到编译时 119 120变更前 121 122```ts 123// declaration.ets 124export class NonSendableClass {}; 125 126// main.ets 127import { NonSendableClass } from './declaration'; 128import collections from '@arkts.collections'; 129 130@Sendable 131class SendableClass { 132 private arr: collections.Array<NonSendableClass> = new collections.Array(); 133 constructor() { 134 this.arr.push(new NonSendableClass()); // Runtime ERROR 135 } 136} 137let sendableclassObject: SendableClass = new SendableClass(); 138``` 139 140变更后 141 142```ts 143// declaration.ets 144export class NonSendableClass {}; 145 146// main.ets 147import { NonSendableClass } from './declaration'; 148import collections from '@arkts.collections'; 149 150@Sendable 151class SendableClass { 152 private arr: collections.Array<NonSendableClass> = new collections.Array(); // ArkTS compile-time error 153 constructor() { 154 this.arr.push(new NonSendableClass()); 155 } 156} 157let sendableclassObject: SendableClass = new SendableClass(); 158``` 159 160场景二:Sendable对象被当作普通对象使用时,影响:产生不兼容变更新增编译报错 161 162变更前 163 164```ts 165@Sendable 166class SendableClassA<T> { 167 one: string = '1'; 168} 169class NoneSendableClassA<T> { 170 one: string = '1'; 171} 172let sendableObjectA: SendableClassA<NoneSendableClassA<number>> = new SendableClassA(); 173``` 174 175变更后 176 177```ts 178@Sendable 179class SendableClassA<T> { 180 one: string = '1'; 181} 182class NoneSendableClassA<T> { 183 one: string = '1'; 184} 185let sendableObjectA: SendableClassA<NoneSendableClassA<number>> = new SendableClassA(); // ArkTS compile-time error 186``` 187 188**起始 API Level** 189 190ArkTS Sendable语法检查从API 12起启用。 191 192**变更发生版本** 193 194从OpenHarmony SDK 5.0.0.31 开始。 195 196**变更的接口/组件** 197 198不涉及。 199 200**适配指导** 201 202Sendable泛型类的类型必须使用Sendable类型。 203 204## cl.arkcompiler.3 ArkTS Sendable赋值语法规则编译检查完善 205 206**访问级别** 207 208其他 209 210**变更原因** 211 212Sendable赋值时需要遵循一定[使用规则](../../..//application-dev/arkts-utils/arkts-sendable.md#sendable使用规则),但是在Non-sendable对象赋值给Sendable类型的部分场景中,编译没有对应的检查,导致这些场景下的Non-sendable对象被当成Sendable对象使用,运行异常但是没有编译时报错。在本次版本更新中,我们修复了这些场景下Sendable赋值约束的编译时检查,将运行时异常提前到编译时。旨在通过编译时错误,帮助开发者更早发现Sendable使用约束,减少运行时定位成本。 213 214错误对象:使用Sendable类型/接口进行声明,但是被赋值为Non-sendable对象的变量/参数/返回值。 215 216**变更影响** 217 218此变更为不兼容变更。 219 220变更前:Non-sendable对象赋值给Sendable类型的部分场景中,DevEco编辑界面没有错误提示,编译没有报错。 221 222变更后:Non-sendable对象赋值给Sendable类型的部分场景中,DevEco编辑界面有错误提示,编译有报错。 223 224当错误对象被当成Sendable对象使用时,将运行时报错提前到编译期。当错误对象被当做普通对象使用时,运行时不报错但编译期新增报错。变更前,在一些场景下Non-sendable对象可以被赋值给Sendable类型。变更后,Non-sendable对象不可以赋值给Sendable类型。 225 226下面的场景将会报错: 227 228Sendable赋值约束 229 230场景一:当错误对象被当成Sendable对象使用时 231 232变更前 233 234```ts 235// declaration.ets 236export class NonSendableClass {}; 237@Sendable 238export class SendableClass {}; 239 240export class NonSendableClassT<T> {}; 241@Sendable 242export class SendableClassT<T> {}; 243 244// main.ets 245import { NonSendableClass, SendableClass, NonSendableClassT, SendableClassT } from './declaration'; 246import collections from '@arkts.collections'; 247 248@Sendable 249class SendableData { 250 propA: SendableClass = new NonSendableClass(); // Runtime ERROR 251 propB: SendableClassT<number>; 252 propC: SendableClass; 253 propD: SendableClass; 254 propE: SendableClass; 255 256 constructor(sendableT: SendableClassT<number>) { 257 const sendableList: SendableClass[] = [new NonSendableClass()]; 258 this.propB = new NonSendableClassT<number>(); // Runtime ERROR 259 this.propC = this.getSendable(); // Runtime ERROR 260 this.propD = sendableList[0]; // Runtime ERROR 261 this.propE = sendableT; // Runtime ERROR 262 } 263 264 getSendable(): SendableClass { 265 return new NonSendableClass(); 266 } 267} 268 269new SendableData(new NonSendableClassT<number>()); 270 271const sendable: SendableClassT<number> = new NonSendableClassT<number>(); 272const sendableArray: collections.Array<SendableClass> = new collections.Array<SendableClass>(); 273sendableArray.push(sendable); // Runtime ERROR 274 275``` 276 277变更后 278 279```ts 280// declaration.ets 281export class NonSendableClass {}; 282@Sendable 283export class SendableClass {}; 284 285export class NonSendableClassT<T> {}; 286@Sendable 287export class SendableClassT<T> {}; 288 289// main.ets 290import { NonSendableClass, SendableClass, NonSendableClassT, SendableClassT } from './declaration'; 291import collections from '@arkts.collections'; 292 293@Sendable 294class SendableData { 295 propA: SendableClass = new NonSendableClass(); // ArkTS compile-time error 296 propB: SendableClassT<number>; 297 propC: SendableClass; 298 propD: SendableClass; 299 propE: SendableClass; 300 301 constructor(sendableT: SendableClassT<number>) { 302 const sendableList: SendableClass[] = [new NonSendableClass()]; // ArkTS compile-time error 303 this.propB = new NonSendableClassT<number>(); // ArkTS compile-time error 304 this.propC = this.getSendable(); 305 this.propD = sendableList[0]; 306 this.propE = sendableT; 307 } 308 309 getSendable(): SendableClass { 310 return new NonSendableClass(); // ArkTS compile-time error 311 } 312} 313 314new SendableData(new NonSendableClassT<number>()); // ArkTS compile-time error 315 316const sendable: SendableClassT<number> = new NonSendableClassT<number>(); // ArkTS compile-time error 317const sendableArray: collections.Array<SendableClass> = new collections.Array<SendableClass>(); 318sendableArray.push(sendable); 319 320``` 321 322场景二:错误对象被当作普通对象使用时,影响:产生不兼容变更新增报错 323 324变更前 325 326```ts 327class NonSendableClass {}; 328@Sendable 329class SendableClass {}; 330 331class NonSendableClassT<T> {}; 332@Sendable 333class SendableClassT<T> {}; 334 335function getSendable(): SendableClass { 336 return new NonSendableClass(); 337} 338 339const objectA: SendableClass = getSendable(); 340const objectB: SendableClassT<number> = new NonSendableClassT<number>(); 341 342``` 343 344变更后 345 346```ts 347class NonSendableClass {}; 348@Sendable 349class SendableClass {}; 350 351class NonSendableClassT<T> {}; 352@Sendable 353class SendableClassT<T> {}; 354 355function getSendable(): SendableClass { 356 return new NonSendableClass(); // ArkTS compile-time error 357} 358 359const objectA: SendableClass = getSendable(); 360const objectB: SendableClassT<number> = new NonSendableClassT<number>(); // ArkTS compile-time error 361 362``` 363 364**起始 API Level** 365 366ArkTS Sendable语法检查从API 12起启用。 367 368**变更发生版本** 369 370从OpenHarmony SDK 5.0.0.31 开始。 371 372**变更的接口/组件** 373 374不涉及。 375 376**适配指导** 377 378避免把Non-sendable对象赋值给Sendable变量/参数/返回值。