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变量/参数/返回值。