1# 共享容器 2 3## ArkTS容器集 4 5ArkTS共享容器([@arkts.collections (ArkTS容器集)](../reference/apis-arkts/js-apis-arkts-collections.md))是一种在并发任务间共享传输的容器类,可以用于并发场景下的高性能数据传递。功能与Ecmascript262规范定义的容器类似,但仍然有部分差异,具体可见[共享容器与原生API方法的行为差异对比](#共享容器与原生api方法的行为差异对比)。 6 7ArkTS共享容器在多个并发任务间传递时,其默认行为是引用传递,支持多个并发任务可以操作同一个容器实例。另外,也支持拷贝传递,即每个并发任务持有一个ArkTS容器实例。 8 9ArkTS共享容器并不是线程安全的,内部使用了fail-fast(快速失败)机制,即当检测多个并发实例同时对容器进行结构性改变时,会触发异常。因此,在容器内修改属性的场景下,开发者需要使用ArkTS提供的[异步锁](arkts-async-lock-introduction.md)机制保证ArkTS容器的安全访问。 10 11ArkTS共享容器包含如下几种:[Array](../reference/apis-arkts/js-apis-arkts-collections.md#collectionsarray)、[Map](../reference/apis-arkts/js-apis-arkts-collections.md#collectionsmap)、[Set](../reference/apis-arkts/js-apis-arkts-collections.md#collectionsset)、[TypedArray](../reference/apis-arkts/js-apis-arkts-collections.md#collectionstypedarray)(Int8Array、Uint8Array、Int16Array、Uint16Array、Int32Array、Uint32Array、Uint8ClampedArray、Float32Array)、[ArrayBuffer](../reference/apis-arkts/js-apis-arkts-collections.md#collectionsarraybuffer)等,具体可见[@arkts.collections (ArkTS容器集)](../reference/apis-arkts/js-apis-arkts-collections.md)。 12 13容器集使用示例如下: 14 15```ts 16import { ArkTSUtils, collections, taskpool } from '@kit.ArkTS'; 17 18@Concurrent 19async function add(arr: collections.Array<number>, lock: ArkTSUtils.locks.AsyncLock) { 20 await lock.lockAsync(() => { // 如果不添加异步锁,任务会因为数据竞争冲突,导致抛异常失败 21 arr[0]++; 22 }) 23} 24 25@Entry 26@Component 27struct Index { 28 @State message: string = 'Hello World'; 29 30 build() { 31 RelativeContainer() { 32 Text(this.message) 33 .id('HelloWorld') 34 .fontSize(50) 35 .fontWeight(FontWeight.Bold) 36 .alignRules({ 37 center: { anchor: '__container__', align: VerticalAlign.Center }, 38 middle: { anchor: '__container__', align: HorizontalAlign.Center } 39 }) 40 .onClick(() => { 41 let taskGroup = new taskpool.TaskGroup(); 42 let lock = new ArkTSUtils.locks.AsyncLock(); 43 let arr = collections.Array.create<number>(1, 0); 44 let count = 1000; 45 while (count--) { 46 taskGroup.addTask(add, arr, lock); 47 } 48 taskpool.execute(taskGroup).then(() => { 49 console.info(`Return success: ${arr[0]} === ${count}`); 50 }).catch((e: Error) => { 51 console.error("Return error."); 52 }) 53 }) 54 } 55 .height('100%') 56 .width('100%') 57 } 58} 59``` 60 61## 共享容器与原生API方法的行为差异对比 62 63ArkTS提供了Sendable数据相关的共享容器集,接口行为与原生API存在部分差异,具体可见下文对比。 64 65> **说明:** 66> 67> ArkTS共享容器的类型与Ecmascript262规范定义的原生容器的类型不一致,因此采用原生容器Array的isArray()方法判断collections.Array实例对象会返回false。 68 69### Array 70 71支持原生容器Array通过[collections.Array.from](../reference/apis-arkts/js-apis-arkts-collections.md#from)方法转换为ArkTS Array容器;支持通过原生容器Array的from方法将ArkTS Array容器转换为原生容器Array。 72 73| 原生API方法 | ArkTS容器集方法 | 是否有行为差异 | 在ArkTS容器中的差异表现 | 74| -------- | -------- | -------- | -------- | 75| length: number | readonly length: number | 是 | 为了防止undefined扩散,不允许设置length。 | 76| new(arrayLength ?: number): any[] | static create(arrayLength: number, initialValue: T): Array | 是 | 为了防止undefined扩散,构造函数中必须提供一个初始值的构造函数。 | 77| new <T>(arrayLength: number): T[] | constructor() | 否 | / | 78| new <T>(...items: T[]): T[] | constructor(first: T, ...left: T[]) | 是 | 为了防止undefined扩散,构造函数中必须提供一个初始值的构造函数,继承场景下,无法调用该函数进行对象构造。 | 79| from<T>(arrayLike: ArrayLike<T>): T[] | static from<T>(arrayLike: ArrayLike<T>): Array<T> | 否 | / | 80| pop(): T \| undefined | pop(): T \| undefined | 是 | 不允许在遍历、访问过程中进行元素的增、删、改操作,否则会抛出异常。 | 81| push(...items: T[]): number | push(...items: T[]): number | 是 | 不允许在遍历、访问过程中进行元素的增、删、改操作,否则会抛出异常。 | 82| concat(...items: ConcatArray<T>[]): T[] | concat(...items: ConcatArray<T>[]): Array<T> | 是 | 不允许在遍历、访问过程中进行元素的增、删、改操作,否则会抛出异常。 | 83| concat(...items: (T \| ConcatArray<T>)[]): T[] | concat(...items: ConcatArray<T>[]): Array<T> | 是 | 不允许在遍历、访问过程中进行元素的增、删、改操作,否则会抛出异常。 | 84| join(separator?: string): string | join(separator?: string): string | 否 | / | 85| shift(): T \| undefined | shift(): T \| undefined | 是 | 不允许在遍历、访问过程中进行元素的增、删、改操作,否则会抛出异常。 | 86| slice(start?: number, end?: number): T[] | slice(start?: number, end?: number): Array<T> | 否 | / | 87| sort(compareFn?: (a: T, b: T) => number): this | sort(compareFn?: (a: T, b: T) => number): Array<T> | 是 | 1. 不允许在遍历、访问过程中进行元素的增、删、改操作,否则会抛出异常。<br/>2. 继承场景下,无法获得实际类型的返回值。 | 88| unshift(...items: T[]): number | unshift(...items: T[]): number | 是 | 不允许在遍历、访问过程中进行元素的增、删、改操作,否则会抛出异常。 | 89| indexOf(searchElement: T, fromIndex?: number): number | indexOf(searchElement: T, fromIndex?: number): number | 否 | / | 90| forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void | forEach(callbackFn: (value: T, index: number, array: Array<T>) => void): void | 是 | ArkTS不支持this,因此不支持thisArg参数。 | 91| map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[] | map<U>(callbackFn: (value: T, index: number, array: Array<T>) => U): Array<U> | 是 | ArkTS不支持this,因此不支持thisArg参数。 | 92| filter(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): T[] | filter(predicate: (value: T, index: number, array: Array<T>) => boolean): Array<T> | 是 | ArkTS不支持this,因此不支持thisArg参数。 | 93| reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T | reduce(callbackFn: (previousValue: T, currentValue: T, currentIndex: number, array: Array<T>) => T): T | 否 | / | 94| reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U | reduce<U>(callbackFn: (previousValue: U, currentValue: T, currentIndex: number, array: Array<T>) => U, initialValue: U): U | 否 | / | 95| [n: number]: T | [index: number]: T | 是 | 不允许在遍历、访问过程中进行元素的增、删、改操作,否则会抛出异常。 | 96| findIndex(predicate: (value: T, index: number, obj: T[]) => unknown, thisArg?: any): number | findIndex(predicate: (value: T, index: number, obj: Array<T>) => boolean): number | 是 | ArkTS不支持this,因此不支持thisArg参数。 | 97| fill(value: T, start?: number, end?: number): this | fill(value: T, start?: number, end?: number): Array<T> | 是 | 1. 不允许在遍历、访问过程中进行元素的增、删、改操作,否则会抛出异常。<br/>2. 继承场景下,无法获得实际类型的返回值。 | 98| entries(): IterableIterator<[number, T]> | entries(): IterableIterator<[number, T]> | 否 | / | 99| keys(): IterableIterator<number> | keys(): IterableIterator<number> | 否 | / | 100| values(): IterableIterator<T> | values(): IterableIterator<T> | 否 | / | 101| includes(searchElement: T, fromIndex?: number): boolean | includes(searchElement: T, fromIndex?: number): boolean | 否 | / | 102| at(index: number): T \| undefined | at(index: number): T \| undefined | 否 | / | 103 104### ArrayBuffer 105 106| 原生API方法 | ArkTS容器集方法 | 是否有行为差异 | 在ArkTS容器中的差异表现 | 107| -------- | -------- | -------- | -------- | 108| readonly byteLength: number | readonly byteLength: number | 否 | / | 109| slice(begin: number, end?: number): ArrayBuffer | slice(begin: number, end?: number): ArrayBuffer | 否 | / | 110| new(byteLength: number): ArrayBuffer | constructor(byteLength: number) | 否 | / | 111 112### TypedArray(以Int8Array为例) 113 114支持原生容器TypedArray通过[collections.TypedArray.from](../reference/apis-arkts/js-apis-arkts-collections.md#from-1)方法转换为ArkTS TypedArray容器;支持通过原生容器TypedArray的from方法将ArkTS TypedArray容器转换为原生容器TypedArray。 115 116| 原生API方法 | ArkTS容器集方法 | 是否有行为差异 | 在ArkTS容器中的差异表现 | 117| -------- | -------- | -------- | -------- | 118| readonly buffer: ArrayBufferLike | readonly buffer: ArrayBuffer | 否 | / | 119| readonly byteLength: number | readonly byteLength: number | 否 | / | 120| readonly byteOffset: number | readonly byteOffset: number | 否 | / | 121| readonly length: number | readonly length: number | 否 | / | 122| readonly BYTES_PER_ELEMENT: number | static readonly BYTES_PER_ELEMENT: number | 否 | / | 123| copyWithin(target: number, start: number, end?: number): this | copyWithin(target: number, start: number, end?: number): Int8Array | 是 | 不允许在遍历、访问过程中进行元素的增、删、改操作否则会抛出异常。 | 124| every(predicate: (value: number, index: number, array: Int8Array) => unknown, thisArg?: any): boolean | every(predicate: TypedArrayPredicateFn<number, Int8Array>): boolean | 是 | 1. 不允许在遍历、访问过程中进行元素的增、删、改操作否则会抛出异常。<br/>2. ArkTS不支持this,因此不支持thisArg参数。 | 125| fill(value: number, start?: number, end?: number): this | fill(value: number, start?: number, end?: number): Int8Array | 是 | 不允许在遍历、访问过程中进行元素的增、删、改操作否则会抛出异常。 | 126| filter(predicate: (value: number, index: number, array: Int8Array) => any, thisArg?: any): Int8Array | filter(predicate: TypedArrayPredicateFn<number, Int8Array>): Int8Array | 是 | 1. 不允许在遍历、访问过程中进行元素的增、删、改操作否则会抛出异常。<br/>2. ArkTS不支持this,因此不支持thisArg参数。 | 127| find(predicate: (value: number, index: number, obj: Int8Array) => boolean, thisArg?: any): number \| undefined | find(predicate: TypedArrayPredicateFn<number, Int8Array>): number \| undefined | 是 | 1. 不允许在遍历、访问过程中进行元素的增、删、改操作否则会抛出异常。<br/>2. ArkTS不支持this,因此不支持thisArg参数。 | 128| findIndex(predicate: (value: number, index: number, obj: Int8Array) => boolean, thisArg?: any): number | findIndex(predicate: TypedArrayPredicateFn<number, Int8Array>): number | 是 | ArkTS不支持this,因此不支持thisArg参数。 | 129| forEach(callbackfn: (value: number, index: number, array: Int8Array) => void, thisArg?: any): void | forEach(callbackFn: (value: number, index: number, array: Int8Array) => void): void | 是 | 1. 不允许在遍历、访问过程中进行元素的增、删、改操作否则会抛出异常。<br/>2. ArkTS不支持this,因此不支持thisArg参数。 | 130| indexOf(searchElement: number, fromIndex?: number): number | indexOf(searchElement: number, fromIndex?: number): number | 否 | / | 131| join(separator?: string): string | join(separator?: string): string | 否 | / | 132| map(callbackfn: (value: number, index: number, array: Int8Array) => number, thisArg?: any): Int8Array | map(callbackFn: TypedArrayForEachCallback<number, Int8Array>): Int8Array | 是 | 1. 不允许在遍历、访问过程中进行元素的增、删、改操作否则会抛出异常。<br/>2. ArkTS不支持this,因此不支持thisArg参数。 | 133| reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number): number | reduce(callbackFn: TypedArrayReduceCallback<number, number, Int8Array>): number | 否 | / | 134| reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number, initialValue: number): number | reduce(callbackFn: TypedArrayReduceCallback<number, number, Int8Array>, initialValue: number): number | 否 | / | 135| reduce<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int8Array) => U, initialValue: U): U | reduce<U>(callbackFn: TypedArrayReduceCallback<U, number, Int8Array>, initialValue: U): U | 否 | / | 136| reverse(): Int8Array | reverse(): Int8Array | 否 | / | 137| set(array: ArrayLike<number>, offset?: number): void | set(array: ArrayLike<number>, offset?: number): void | 是 | 不允许在遍历、访问过程中进行元素的增、删、改操作否则会抛出异常。 | 138| slice(start?: number, end?: number): Int8Array | slice(start?: number, end?: number): Int8Array | 否 | / | 139| some(predicate: (value: number, index: number, array: Int8Array) => unknown, thisArg?: any): boolean | some(predicate: TypedArrayPredicateFn<number, Int8Array>): boolean | 是 | ArkTS不支持this,因此不支持thisArg参数。 | 140| sort(compareFn?: (a: number, b: number) => number): this | sort(compareFn?: TypedArrayCompareFn<number>): Int8Array | 是 | 1. 不允许在遍历、访问过程中进行元素的增、删、改操作否则会抛出异常。<br/>2. 继承场景下,无法获得实际类型的返回值。 | 141| subarray(begin?: number, end?: number): Int8Array | subarray(begin?: number, end?: number): Int8Array | 是 | 不允许在遍历、访问过程中进行元素的增、删、改操作否则会抛出异常。 | 142| [index: number]: number | [index: number]: number | 是 | 不允许在遍历、访问过程中进行元素的增、删、改操作否则会抛出异常。 | 143| entries(): IterableIterator<[number, number]> | entries(): IterableIterator<[number, number]> | 否 | / | 144| keys(): IterableIterator<number> | keys(): IterableIterator<number> | 否 | / | 145| values(): IterableIterator<number> | values(): IterableIterator<number> | 否 | / | 146| includes(searchElement: number, fromIndex?: number): boolean | includes(searchElement: number, fromIndex?: number): boolean | 否 | / | 147| at(index: number): number \| undefined | at(index: number): number \| undefined | 否 | / | 148| new(length: number): Int8Array | constructor(length: number) | 否 | / | 149| new(array: ArrayLike<number> \| ArrayBufferLike): Int8Array | constructor(array: ArrayLike<number> \| ArrayBuffer) | 否 | / | 150| new(buffer: ArrayBufferLike, byteOffset?: number, length?: number): Int8Array | constructor(buffer: ArrayBuffer, byteOffset?: number, length?: number) | 否 | / | 151| from(arrayLike: ArrayLike<number>): Int8Array | static from(arrayLike: ArrayLike<number>): Int8Array | 否 | / | 152| from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => number, thisArg?: any): Int8Array | static from<T>(arrayLike: ArrayLike<T>, mapFn: TypedArrayFromMapFn<T, number>): Int8Array | 是 | ArkTS不支持this,因此不支持thisArg参数。 | 153| from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number, thisArg?: any): Int8Array | static from(arrayLike: Iterable<number>, mapFn?: TypedArrayFromMapFn<number, number>): Int8Array | 是 | ArkTS不支持this,因此不支持thisArg参数。 | 154 155### Map 156 157| 原生API方法 | ArkTS容器集方法 | 是否有行为差异 | 在ArkTS容器中的差异表现 | 158| -------- | -------- | -------- | -------- | 159| readonly size: number | readonly size: number | 是 | 不允许在遍历、访问过程中进行元素的增、删、改操作否则会抛出异常。 | 160| clear(): void | clear(): void | 是 | 不允许在遍历、访问过程中进行元素的增、删、改操作否则会抛出异常。 | 161| delete(key: K): boolean | delete(key: K): boolean | 是 | 不允许在遍历、访问过程中进行元素的增、删、改操作否则会抛出异常。 | 162| forEach(callbackfn: (value: V, key: K, map: Map<K, V>) => void, thisArg?: any): void | forEach(callbackFn: (value: V, key: K, map: Map<K, V>) => void): void | 是 | 1. 不允许在遍历、访问过程中进行元素的增、删、改操作否则会抛出异常。<br/>2. ArkTS不支持this,因此不支持thisArg参数。 | 163| get(key: K): V \| undefined | get(key: K): V \| undefined | 是 | 不允许在遍历、访问过程中进行元素的增、删、改操作否则会抛出异常。 | 164| has(key: K): boolean | has(key: K): boolean | 是 | 不允许在遍历、访问过程中进行元素的增、删、改操作否则会抛出异常。 | 165| set(key: K, value: V): this | set(key: K, value: V): Map<K, V> | 是 | 不允许在遍历、访问过程中进行元素的增、删、改操作否则会抛出异常。 | 166| entries(): IterableIterator<[K, V]> | entries(): IterableIterator<[K, V]> | 否 | / | 167| keys(): IterableIterator<K> | keys(): IterableIterator<K> | 否 | / | 168| values(): IterableIterator<V> | values(): IterableIterator<V> | 否 | / | 169| new <K, V>(entries?: readonly (readonly [K, V])[] \| null): Map<K, V> | constructor(entries?: readonly (readonly [K, V])[] \| null) | 是 | 构造时传入的k,v键值不能是非Sendable数据,否则编译会报错。 | 170 171### Set 172 173| 原生API方法 | ArkTS容器集方法 | 是否有行为差异 | 在ArkTS容器中的差异表现 | 174| -------- | -------- | -------- | -------- | 175| readonly size: number | readonly size: number | 是 | Sendable类和接口中不允许使用计算属性名称(arkts-sendable-compated-prop-name)。 | 176| add(value: T): this | add(value: T): Set<T> | 是 | 不允许在遍历、访问过程中进行元素的增、删、改操作否则会抛出异常。 | 177| clear(): void | clear(): void | 是 | 不允许在遍历、访问过程中进行元素的增、删、改操作否则会抛出异常。 | 178| delete(value: T): boolean | delete(value: T): boolean | 是 | 不允许在遍历、访问过程中进行元素的增、删、改操作否则会抛出异常。 | 179| forEach(callbackfn: (value: T, value2: T, set: Set<T>) => void, thisArg?: any): void | forEach(callbackFn: (value: T, value2: T, set: Set<T>) => void): void | 是 | 1. 不允许在遍历、访问过程中进行元素的增、删、改操作否则会抛出异常。<br/>2. ArkTS不支持this,因此不支持thisArg参数。 | 180| has(value: T): boolean | has(value: T): boolean | 是 | 不允许在遍历、访问过程中进行元素的增、删、改操作否则会抛出异常。 | 181| entries(): IterableIterator<[T, T]> | entries(): IterableIterator<[T, T]> | 否 | / | 182| keys(): IterableIterator<T> | keys(): IterableIterator<T> | 否 | / | 183| values(): IterableIterator<T> | values(): IterableIterator<T> | 是 | Sendable类和接口中不允许使用计算属性名称(arkts-sendable-compated-prop-name)。 | 184| new <T = any>(values?: readonly T[] \| null): Set<T> | constructor(values?: readonly T[] \| null) | 是 | 构造时传入数据不能是非Sendable数据,否则编译会报错。 | 185