类型作为位

Elm 中有各种类型

  • Bool
  • Int
  • String
  • (Int, Int)
  • Maybe Int
  • ...

我们现在对它们有概念上的理解,但计算机如何理解它们?Maybe Int 如何存储在硬盘上?

是一种具有两种状态的小盒子。0 或 1。开或关。计算机内存是位的一串超长序列。

好的,我们所拥有的就是一堆位。现在我们需要用它来表示所有内容

Bool

Bool 值可以是 TrueFalse。这完全对应于一位!

Int

Int 值是像 012 等整数。你无法将它放在一位中,因此唯一的其他选择就是使用多个位。因此,通常,Int 将是一个位序列,如下所示

00000000
00000001
00000010
00000011
...

我们可以任意地为每个序列指定意义。所以也许 00000000 是 0,00000001 是 1。太棒了!我们可以按升序开始向位序列分配数字。但最终我们会用光位...

通过一些快速的计算,8 位只允许 (2^8 = 256) 个数字。那么 9000 和 8004 等非常合理的数字又会怎么样呢?

答案是只需添加更多位。很长一段时间内,人们使用 32 位。这允许有 (2^32 = 4,294,967,296) 个数字,它涵盖了人类通常会想到的数字类型。如今的计算机支持 64 位整数,允许有 (2^64 = 18,446,744,073,709,551,616) 个数字。这很多!

注意:如果你好奇加法如何运作,请了解二进制补码。它揭示了数字并非随意分配给位序列。为了使加法尽可能快,这种分配数字的特定方式非常有效。

String

字符串"abc"是字符a b c的序列,因此我们将尝试将字符表示为二进制位序列。

早期的一种字符编码方式称为ASCII。与整数类似,它们决定列出一堆二进制位序列,并开始任意地分配值

00000000
00000001
00000010
00000011
...

因此每个字符需要由八个二进制位表示,这意味着只能表示 256 个字符!但如果你只关心英语,这实际上非常有效。你需要涵盖 26 个小写字母、26 个大写字母和 10 个数字。共有 62 个。还剩很多空间可用于符号和其他奇奇怪怪的东西。你可以看到他们最终得到了这里的内容。

现在我们对字符有了一个想法,但计算机如何知道String在哪里结束以及下一条数据从哪里开始?这只是一些二进制位。字符看起来真得就像Int值!因此,我们需要某种方法来标记结束。

如今,语言倾向于通过存储字符串的长度来实现此目的。因此,像"hello"这样的字符串在内存中可能看起来像5 h e l l o。因此,你知道一个String始终以表示该长度的 32 个二进制位开头。无论长度是 0 还是 9000,你都知道字符的结束位置。

注意:在某种程度上,人们想涵盖英语之外的语言。这项工作最终导致了UTF-8编码。它确实非常出色,我鼓励你了解它。事实证明,“获取第 5 个字符”比听起来要难!

(Int, Int)

哪一个元组呢?好,(Int, Int)是两个Int值,每个值都是二进制位序列。让我们将这两个序列放在内存中的紧挨着,然后休息一下!

自定义类型

自定义类型全是关于组合不同类型。这些不同的类型可能具有各种不同的形状。我们从Color类型开始

type Color = Red | Yellow | Green

我们可以为每个案例分配一个数字:Red = 0Yellow = 1Green = 2。现在,我们可以使用Int表示法。这里我们只需要两个二进制位来涵盖所有可能的情况,因此00是红色、01是黄色、10是绿色,而11则未使用。

但是,对于那些保存其他数据的自定义类型怎么办?像是Maybe Int?典型的方法是预留一些二进制位来“标记”数据,这样我们可以决定Nothing = 0Just = 1。以下是一些示例

  • Nothing = 0
  • Just 12 = 1 00001100
  • Just 16 = 1 00010000

case 表达式始终在决定下一步做什么之前查看这个“标签”。如果它看到一个 0,则它知道没有更多数据。如果它看到一个 1,则它知道后跟代表数据的一系列位。

这个“标签”的想法类似于将长度放在 String 值的开头。这些值大小可能不同,但代码始终可以弄清楚它们从哪里开始和结束。

摘要

最终,所有值都需要以位来表示。此页面粗略地概述了它的实际工作原理。

通常没有真正的理由去考虑这个,但我发现它有助于加深我对自定义类型和 case 表达式的理解。我也希望它对你有帮助!

注意: 如果你认为这很有趣,那么了解有关垃圾回收的更多信息可能会很有趣。我发现垃圾回收手册 是一个关于该主题的优秀资源!

匹配""

    没有匹配""的结果