<Programming with Types>随想: Chapter 2. Basic types

Search for a command to run...

No comments yet. Be the first to comment.
C++程序设计兼谈对象模型-导读 conversion function, 转换函数 class Fraction { public: Fraction(int num, int den=1) : m_numerator(num), m_denominator(den){}; operator double() const { return 1.0 * m_numerator / m_denominator; } private: int m_n...

头文件与类声明 Classes 两个分类 Class without pointer member(s): complex Class with pointer member(s): string 也可以分为 Object-Based vs Object Oriented 构造函数 inline函数 函数如果在 class 内定义完成,则自动成为 inline 候选人. 也可以在class 外部定义,方法需要增加inline 关键字。 constructor(ctor, 构造函数) ...

不同于 Chapter03 从系统的角度来处理数据,这一章从数据科学的视角来处理数据。这章的标题是“training Data”,而非“training dataset”,因为 数据集(dataset) 意味着有限(finite)和固定(stationary), 而现实生产环境中的 数据(data) 通常是 无限 并且 不固定 的。 抽样 抽样方法在 ML 项目的生命周期中无处不在,在这一节中,我们使用生成训练数据作为例子。 那为什么需要抽样?直接使用全部数据不可以吗? 首先,在现实世界中,并不...

这一章大部分内容和DDIA很相似,作者也说 “If you’re already familiar with data systems, you might want to move directly to Chapter 4 to learn more about how to sample and generate labels to create training data. If you want to learn more about data engineering from a...

类型限制了一个变量可以接受的有效值的集合,对数据可以进行的操作,数据的意义。
根据类型的定义,类型定义了可以接受的有效值集合,那么这个集合有没有可能为空?答案是有可能的,TypeScirpt 的 never 就是这种类型。
需要注意的是,空类型不同与 void, 后者是有效值集合当中只有一个值,但这个值没有任何意义。而空类型的有效值集合本身是空的。
在函数调用时,标志一个函数不会返回任何值: 在调用过程中抛出异常、死循环或者程序崩溃。即返回值类型为 never 的函数,不会将CPU的控制权返回给被调函数。
function raise(message: string): never {
throw new Error(message);
}
function forever(): never {
while (true) {}
}
如果返回实际的值或者在调用处后面的继续编写代码逻辑,会引起编译错误。
function main() {
forever()
console.log(1); // Unreachable code detected.(7027)
}
当业务中有一个 union type
interface Foo {
type: 'foo'
}
interface Bar {
type: 'bar'
}
type All = Foo | Bar
在 switch 当中判断 type,TS 是可以收窄类型的 (discriminated union):
function handleValue(val: All) {
switch (val.type) {
case 'foo':
// 这里 val 被收窄为 Foo
break
case 'bar':
// val 在这里是 Bar
break
default:
// val 在这里是 never
const exhaustiveCheck: never = val
break
}
}
注意在 default 里面我们把被收窄为 never 的 val 赋值给一个显式声明为 never 的变量。如果一切逻辑正确,那么这里应该能够编译通过。但是假如后来有一天你的同事改了 All 的类型:
type All = Foo | Bar | Baz
然而他忘记了在 handleValue 里面加上针对 Baz 的处理逻辑,这个时候在 default branch 里面 val 会被收窄为 Baz,导致无法赋值给 never,产生一个编译错误。所以通过这个办法,你可以确保 handleValue 总是穷尽 (exhaust) 了所有 All 的可能类型。
参考链接:https://www.zhihu.com/question/354601204
never 是任何类型的 subtype(子类型), 除了never,没有其他类型是never的subtype。
这个例子体现 never 的取值有效集是空集,在 TS 中,可以对类型做集合的交并运算。 never 是 union(并集) 运算的幺元,intersection(交集)运算的零元.
T | never // 结果为T
T & never // 结果为never
单元类型的取值有效集集合中,只有一个值, 因此编译器不需要处理单元类型的具体值。
常见的单元类型有
// undefined类型。
let a: undefined = undefined;
// null类型。
let b: null = null;
// unique symbol类型。
const c: unique symbol = Symbol();
// void类型。
let d: void = undefined;
// 字面量类型。
const e: 'hello' = 'hello';
// 联合枚举成员类型。
enum Foo { A, B }
const f: Foo.A = Foo.A;
也有人认为 void is not a unit type in TypeScript
当一个函数返回值为单元类型时,这个值没有任何含义,因为无论函数内部发生什么,正常执行都会返回这个类型,并且只有该类型只有一个值。
这种没有返回任何有意义值的函数,通常被称为actions 或者 consumers, 他们存在的目的是为了产生副作用,对现实世界产生影响,例如 console.log()
boolean 类型存在短路逻辑,如果第一个操作数(operand)提供了足够的信息评估(evaluate)整个表达式,那么第二个操作数就不会被 evaluate.
基础的二进制编码,补码,IEEE754方式,此处略去。
Unicode编码有几个相似但是截然不同的概念:
字符(Characters): 文本的计算机表示, 警官emoji(👮),零宽字符,女性标志(🚺)都是字符。字符这个词在不同的上下文环境中经常会被赋予不同的意思。
字位(graphemes): 用户看到的符号,在渲染文本时,我们使用的是字位(graphemes),我们不想把一个多字的字位(multiple-character grapheme)拆开。
glygh(字形): "字形 "是一个字符的特殊表现形式。"C"(粗体)和 "C"(斜体)是 "C "字的两种不同的视觉表现形式。
code point(码点) 是文本信息的原子单位。文本是一连串的代码点。每个代码点是一个数字,由Unicode标准赋予其意义。
code unit(码元) 编码组成 code point(码点) 的一部分. In UTF-8 this means 8 bits, in UTF-16 this means 16 bits. A single code unit may represent a full code point, or part of a code point. For example, the snowman glyph (☃) is a single code point but 3 UTF-8 code units, and 1 UTF-16 code unit.
UTF-32 是一种长度不可变的字符串编码方式,对于每一个grapheme都使用,32bit存储,但是会造成格外的空间浪费。
UTF-8 和 UTF-16 是长度可变的编码方式(variable-length encodings).