标量与原始数据类型-它们是相同的吗?

189

在我阅读的各种文章中,有时会提到原始数据类型,有时也会提到标量。

我的理解是它们都是一些简单的数据类型,例如 int、boolean、char 等。

是否有什么我忽略了的因素,导致应该使用特定的术语,或者这些术语只是可以互换使用的呢? 维基百科的页面并没有显示任何明显的区别。

如果这些术语只是可以互换使用的话,那么哪一个更受欢迎呢?

8个回答

288

我认为它们不是可以互换的。它们常常相似,但是存在区别,主要在于它们所对比的对象和上下文中的相关性。

标量通常与复合类型对比,例如数组、映射、集合、结构等。标量是一个“单一”的值 - 整数、布尔值,可能是字符串 - 而复合类型由多个标量(以及可能是其他复合类型的引用)组成。“标量”在上下文中适用于单个/简单/原子值和复合值之间的相关区别。

然而,基本类型则与例如引用类型相对应,并且当相关区别是“这是直接的值,还是它是指向包含真实值的东西的引用?”时使用,例如Java的基本类型与引用类型。我认为这是比标量/复合类型略低级别的区别,但并不完全相同。

它真的取决于上下文(通常是正在讨论的语言家族)。以一个可能是病态的例子为例:字符串。在C中,字符串是复合类型(字符数组),而在Perl中,字符串是标量。在Java中,字符串是对象(或引用类型)。在Python中,所有内容(概念上)都是对象/引用类型,包括字符串(和数字)。


1
在讨论引用类型和基本类型时,还应考虑“值”类型。关于标量和原始类型的等价性,这取决于语言。例如,根据PHP手册,只有其原始类型的一半是标量:http://php.net/manual/en/language.types.intro.php - Joe Bowbeer
我认为引用类型也表示复合值,因为它具有内存地址和数据类型。 C字符串也是复合类型,因为它们使用指针。标量意味着大小,因此将它们与复合物对比感觉不直观或简单错误。而且,布尔值并不表示大小,所以它们不是标量。看起来程序员在命名事物时没有注意到其含义或影响。 - snnsnn
在静态类型语言中,数据类型不会与内存地址一起存储,只有地址被存储。在动态类型语言中,指针通常指向某种包含数据类型的语言结构;然而,虽然 实现 可能是复合的,但其对于实现的语言的 语义 可能是“标量”的。我的目的是按照实际用于描述 PL 语义的术语来描述这些术语; Perl 在此处讨论了标量的使用。我相信 R 也是如此。许多编程语言不使用这个术语。 - Michael Ekstrand
@MichaelEkstrand 对不起,我的意思是地址和数据。 - snnsnn

35

有很多混淆和误用这些术语。通常一个词被用来代表另一个。以下是这些术语的实际含义。

"Native" 指内置于语言中的类型,而不是由库(即使是标准库)提供的,不管它们如何实现。Perl字符串是Perl语言的一部分,因此在Perl中它们是本地的。C使用库将字符串语义覆盖到指向字符的指针上,因此指向字符是本地的,但字符串不是。

"Atomic" 指不能再分解的类型。它是"composite"的相反。组合可以被拆分成原子值或其他组合的组合。本地整数和浮点数是原子的。分数、复数、容器/集合和字符串是组合的。

"Scalar" - 这是最让人困惑的一个词 - 指能够表示规模(因此得名)的值,例如大小、体积、计数等。整数、浮点数和分数都是标量。复数、布尔值和字符串不是标量。一个原子并不一定是标量,一个标量也不一定是原子。标量可以是本地的,也可以由库提供。

一些类型有奇怪的分类。BigNumber类型通常被实现为数字或整数数组,它们是标量,但它们技术上不是原子的。如果实现被隐藏并且无法访问内部组件,则它们可能表现为原子。但是这些组件只是隐藏的,因此原子性是一种幻觉。它们几乎总是由库提供,因此它们不是本地的,但它们可以是。例如,在Mathematica编程语言中,大数是本地的,并且由于没有办法将它们分解为其构建块,它们在该上下文中也是原子的,尽管在内部(您不再处于Mathematica语言的世界)它们是组合体。

这些定义与所使用的语言无关。


21
尽管我认为这个标量类型的定义最合理,但这似乎不是最常被接受的定义。 - lleaff
1
感谢对“标量”清晰的定义。尽管,正如@lleaff所指出的,大多数人并不以这种特定的方式使用它,但如果他们这样做会更好。 - clockworkpc
优秀的语言学定义。为了更全面地讨论,建议阅读Michael Ekstrand的回答。在编程语言的上下文中,“scalar”有不同的含义,这是令人遗憾的。 - Jerry

11
简单来说,“标量”类型似乎是指单个项目,而不是组合或集合。因此,标量包括原始值以及诸如枚举值之类的内容。

http://ee.hawaii.edu/~tep/EE160/Book/chap5/section2.1.3.html

也许“标量”这个词可能是对C语言的回溯:
其中,标量是原始对象,它包含一个单一的值,并且不由其他C++对象组成。

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1995/N0774.pdf

我想知道这是否指的是这些项目是否会有一个“scale”的值?-比如计数数字。


3
很久以前在学校里教我的,这个术语源于“标量处理器”,与“矢量处理器”相对应。标量处理器是一种只能一次处理一组数据的中央处理器(CPU),这些处理器按算术术语命名。有趣的是,当你在维基百科上查找“标量”时,会被重定向到“变量”。 - Bert

4
我喜欢Scott Langeberg的答案,因为它简洁明了并支持权威链接。如果可以的话,我会点赞Scott的回答。
我认为“原始”数据类型可以被视为主要数据类型,以便从主要数据类型派生出次要数据类型。派生是通过组合实现的,例如C++结构体。结构体可用于组合数据类型(例如int和char),以获得次要数据类型。由结构体定义的数据类型始终是次要数据类型。主要数据类型不是从任何东西中派生出来的,而是在编程语言中给定的。
我对原始作为主要名称的类比是“正则表达式”。我认为术语“正则”可以理解为“调节”。因此,您有一个调节搜索的表达式。
标量词源学(http://www.etymonline.com/index.php?allowed_in_frame=0&search=scalar&searchmode=none)意味着像梯子一样。我认为这与编程的关系在于梯子只有一个维度:距离梯子末端有多少级。标量数据类型只有一个维度,因此由单个值表示。
我认为在使用中,原始和标量是可以互换的。是否有任何非标量的原始数据类型或非原始的标量数据类型的例子?
虽然可互换,但原始指的是数据类型作为其他数据类型的基本构建块,并且原始数据类型不由其他数据类型组成。
标量指它具有单个值。 标量与数学向量形成对比。 向量不通过单个值来表示,因为(以一种向量为例)需要一个值来表示向量的方向,另一个值来表示向量的大小。
参考链接: http://whatis.techtarget.com/definition/primitive http://en.wikipedia.org/wiki/Primitive_data_type

既然你问了一个非标量原始类型的例子……那么JavaScript中的字符串如何?请查看我的答案以了解其背后的原理。 - Arnel Enero
1
在Javascript中,字符串在所有意义上都是原始的。你可以从typeof运算符或字符串在JSON中的使用方式等方面看出这一点。在Javascript中,如果不考虑nullundefinedbooleannumberstring是唯一的原始类型。是的,你可以“split”一个字符串并得到两个字符串,但你也可以“spit”一个数字并得到两个数字。有趣的是,数学倾向于将质数视为(整数)数字的真正原始构建块,因为质数除了“1”和它本身外不能被任何东西除尽。 - Stijn de Witt

1
“Scalar”与语言无关,而“primitive”的定义则取决于编程语言。两者没有任何关联。

“Scalar”数据类型是指具有一定范围内的可能值,并遵循某种比例尺度,即每个值都可以与其他值进行比较,判断大小或相等。数字(浮点数和整数)很明显属于此类,离散/枚举值也可以被视为标量。在这方面,布尔型是一个只有两个离散可能值的标量,通常情况下true > false。无论编程语言如何,字符串在技术上都不是标量。

现在,“primitive”的定义取决于编程语言。每种语言都会将其“基本类型”分类,并将其指定为原始类型。在JavaScript中,字符串是原始类型,尽管它在一般意义上不是标量。但在某些语言中,字符串并非原始类型。要成为原始类型,语言必须能够将其视为不可变的,并且由于这个原因,引用类型(例如对象、数组、集合)在大多数语言中都不能是原始类型。


1
我认为您答案中提到的“有限”并不正确。是的,浮点数和双精度浮点数由于技术限制而具有有限的可能值,但在我看来,那纯粹是一种技术上的限制。实际上,即使真正拥有无限可能值的实数类型仍然可以被视为“标量”。 - Stijn de Witt
你提到的其他限制,例如可比较性(小于或大于等),仍适用于具有无限值的实数。尽管数轴在0两侧延伸至无穷远,但每个数字仍然可以与任何其他数字进行比较,并且它们都位于这条一维线上。 - Stijn de Witt

0
在C语言中,枚举类型、字符和各种整数表示形式构成了一个更一般的类型类别,称为标量类型。因此,您可以对任何标量类型的值执行的操作与整数相同。

0

空类型是最符合“标量类型”定义的唯一类型。即使将“None”序列化为“N.”,它也适合传统标量类型的16位字或具有多个可能值的单个位--但这并不是“单一数据”。


0

每个原始类型都是标量,但反之不一定成立。DateTime 是标量,但不是原始类型。


在JavaScript中,例如,字符串是一种原始类型。但是从一般意义上讲,无论使用哪种编程语言,字符串都不是标量,因为(1)它没有有限的值范围,(2)您不能将一个字符串与另一个字符串进行比较大小。 - Arnel Enero
实数也没有有限的值集(整数也没有),但它们仍然被视为“标量”,不是吗?事实上,我认为数学中不存在具有有限值集的数字类型?自然数、整数、实数、复数等都有无限可能的值,是吗? - Stijn de Witt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接