简体   繁体   English

是否可以在打字稿中定义 Float32Array 类型的大小?

[英]Is it possible to define the size of a Float32Array type in typescript?

I know that with tuples sizes of arrays can be defined.我知道可以定义数组的元组大小。 Not applicable to float32array which is a class itself though.不适用于 float32array ,但它本身就是一个类。

Can that somehow be done with float32arrays as well?这也可以用 float32arrays 来完成吗?

I tried const foo: FloatArray32[4] but that casts the type directly to the number.我试过const foo: FloatArray32[4]但这将类型直接转换为数字。 I also tried to check if types might be compatible:我还尝试检查类型是否兼容:

let foo: [number, number, number, number];
foo = new Float32Array([1, 2, 3, 4]);

But they are not.但他们不是。

Changing all the types in my code to '[number, number, number, number];'将代码中的所有类型更改为 '[number, number, number, number];' (in my case I need a 4 float array for a point coordinate) is a possibility, although I would need to make changes in quite a lot of places in the code. (在我的情况下,我需要一个点坐标的 4 个浮点数组)是一种可能性,尽管我需要在代码中的很多地方进行更改。

However, I was wondering if there might be a 'childtype' extending Float32Array type, where the number of the elements of the array can be fixed in the type.但是,我想知道是否可能存在扩展 Float32Array 类型的“childtype”,其中数组的元素数量可以在类型中固定。

Javascript typed arrays, are in fact, fixed length - see the docs for your example . Javascript 类型数组实际上是固定长度的 - 请参阅示例文档。 The constructors in particular:特别是构造函数:

new Float32Array(); // new in ES2017 
new Float32Array(length);
new Float32Array(typedArray); 
new Float32Array(object); 
new Float32Array(buffer [, byteOffset [, length]]);

all have the length deducible on creation (that new first one creates an empty array with 0 elements. I guess it simplified some edge cases).所有在创建时都有可推导的长度(新的第一个创建一个包含 0 个元素的空数组。我想它简化了一些边缘情况)。

I'm not sure how you are determining the type, but as soon as you get an item from your array it will be converted to a number, the only number type available in JS - so looking at your log is misleading here.我不确定您是如何确定类型的,但是一旦您从数组中获取一个项目,它就会被转换为一个数字,这是 JS 中唯一可用的数字类型 - 所以在这里查看您的日志会产生误导。 Take a look at the following static property:看看下面的静态属性:

 Float32Array.prototype.byteLength

Returns the length (in bytes) of the Float32Array.返回 Float32Array 的长度(以字节为单位)。 Fixed at construction time and thus read only.在构建时修复,因此只读。

This is the only thing that counts.这是唯一重要的事情。 If you still don't believe the docs, try logging a cell after you overflow it (easier with int8 - put 200 or something).如果您仍然不相信文档,请尝试在溢出后记录单元格(使用int8更容易 - 输入 200 或其他内容)。 This is relevant to your example - nothing is being converted to a number .这与您的示例相关 - 没有任何内容被转换为数字 The array object is a view in fixed length numbers - again, run your test with an Int8Array and try to assign 200 to the cell, and read the cell.数组对象是固定长度数字的视图 - 再次使用Int8Array运行测试并尝试将 200 分配给单元格,然后读取单元格。

This is a view into raw data.这是原始数据的视图 If you extract it and make mathematical operations, you are now in JS realm and working with Numbers - but once you assign stuff back, you better make sure the data fits.如果您提取它并进行数学运算,您现在处于 JS 领域并使用 Numbers - 但是一旦您将内容分配回来,您最好确保数据适合。 You cannot get JS/TS to show you something like float32 in your console, but each cell of the array itself does have an exact byte length.无法让 JS/TS 在您的控制台中向您显示类似float32 ,但数组本身的每个单元格都具有精确的字节长度。

unfortunately , making the length a part of the type is non-trivial within the type system as far as I can tell since the length is a property determined in construction (even if static and read only) and not a part of the type.不幸的是,就我所知,将长度作为类型的一部分在类型系统中并不重要,因为长度是在构造中确定的属性(即使是静态和只读的),而不是类型的一部分。 If you do want something like this a thin wrapper could do the trick:如果您确实想要这样的东西,那么薄包装就可以解决问题:

class vec4 extends Float32Array {
    constructor(initial_values? : [number, number, number, number]) {
    initial_values? super(initial_values) : super(4);
    }
}

would do the trick.会做的伎俩。 If you are willing to give up square brackets you can add index out-of-bound checking in the different methods (you can set in a fixed width array any cell, but it will do nothing, and retrieving it will yield undefined if out of bounds, which may be error prone):如果你愿意放弃方括号,你可以在不同的方法中添加索引越界检查(你可以在一个固定宽度的数组中设置任何单元格,但它什么也不做,如果超出范围,检索它会产生undefined边界,这可能容易出错):

get(index : number) {
    if(index > 4 || index < 0) ...
    return this.private_data[index];
}
set(index : number, value : number) {
    if(index > 4 || index < 0) ...
    this.private_data[index] = value;
}  

Of course, without LSP in JS/TS the array and your class are still interchangeable, so enforcement is really only done on construction, and only if you do not try to break your own code ( let foo : vec4; foo = new Float32Array([1, 2]); etc...).当然,在 JS/TS 中没有 LSP,数组和你的类仍然可以互换,所以执行实际上只在构造时完成,并且只有当你不试图破坏你自己的代码时( let foo : vec4; foo = new Float32Array([1, 2]);等等...)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM