我正在实施加密算法(用于教育目的),我发现了一些奇怪的东西.部分算法使用s-box进行替换,因此我将const数组分配用作查找表,如下所示:
const unsigned char s0_lookup[4][4]={{1,0,3,2},
{3,2,1,0},
{0,2,1,3},
{3,1,3,2}};
const unsigned char s1_lookup[4][4]={{0,1,2,3},
{2,0,1,3},
{3,0,1,0},
{2,1,0,3}};
Run Code Online (Sandbox Code Playgroud)
由于数组使用const限定符,我认为它们应该存储在文本区域而不是堆栈中.但是,如果我对编译器的输出进行反汇编,我会看到:
0000000000000893 <s_des_sbox>:
893: 55 push %rbp
894: 48 89 e5 mov %rsp,%rbp
897: 48 89 7d c8 mov %rdi,-0x38(%rbp)
89b: c6 45 dd 00 movb $0x0,-0x23(%rbp)
89f: c6 45 e0 01 movb $0x1,-0x20(%rbp)
8a3: c6 45 e1 00 movb $0x0,-0x1f(%rbp)
8a7: c6 45 e2 03 movb $0x3,-0x1e(%rbp)
8ab: c6 45 e3 02 movb $0x2,-0x1d(%rbp)
8af: c6 45 e4 03 movb …Run Code Online (Sandbox Code Playgroud) 向JavaScript添加静态类型的全部目的是为类型安全提供一些保证。我注意到,数组索引似乎不使用任何肮脏的技巧(例如,as any或不是null的断言运算符)就破坏了类型安全性。
let a: Array<number> = [1,2,3,4];
let b: number = a[4]; //undefined
Run Code Online (Sandbox Code Playgroud)
该代码不会引起任何TypeScript错误,即使可以清楚地看到它将破坏类型安全。在我看来,Array<T>索引运算符[]所作用的类型应该是type T | undefined,但是TypeScript编译器将其视为type T。
经过进一步调查,我发现此行为也适用于在对象上使用索引运算符。在任何情况下,索引运算符似乎都不安全。
class Example {
property: string;
}
let c: Example = { property: "example string" }
let d: string = c["Not a property name"]; //undefined
Run Code Online (Sandbox Code Playgroud)
在具有任意键的对象上使用索引运算符将返回type any,可以将其分配给任何类型而不会引起类型错误。但是,这可以通过使用--noImplicitAny编译器选项来解决。
我的问题是,为什么在数组中断类型安全性上像索引一样基本呢?这是TypeScript的设计约束,疏忽还是故意的一部分?