8

我听说过很多关于“类型系统”、“强类型语言”等的内容。目前我正在研究一些 .NET COM 互操作问题,它解决了很多“封送”问题。和 AFAIK,封送处理完全是关于 .NET 类型和 COM 类型之间的转换。

在编程语言等很多场景中,谈到类型时,我们关心的是逻辑含义。

现在我想知道:“类型”在物理上是什么意思?在某种程度上,我们可以观看和触摸。

我目前的理解是“类型”只不过是计算实体的内存表示

非常感谢您的回复。

添加-1

来自MSDN的一些引用:

跨托管/非托管边界编组简单的、可blittable 结构首先需要定义每个本机结构的托管版本。这些结构可以有任何合法名称;除了数据布局之外,这两个结构的本机版本和托管版本之间没有任何关系。因此,托管版本包含与本机版本相同大小和顺序的字段至关重要。(没有确保结构的托管版本和本机版本等效的机制,因此不兼容直到运行时才会显现出来。确保两个结构具有相同的数据布局是程序员的责任。)

因此,就编组而言,布局很重要。

4

10 回答 10

15

我认为编程中的“类型”有三个方面(它们可能重叠,所以不要把它当作硬性的分离):

  • 类型是一组类型中的一个元素,每个程序/程序集/单元都定义了这样一个集合。这是我能想到的最理论的想法,可能对逻辑学家和数学家最有用。它非常通用,它允许您在其之上定义类型系统的概念。例如,编程环境可能会在这些类型上定义关系,例如is-assignable-to关系。

  • 类型是语义类别。这是一种语言或认知观念;换句话说,它对正在考虑如何对计算机进行编程的人类最有用。该类型封装了我们所认为的“属于某个类别的事物”。类型可能由实体的共同目的来定义。这种根据目的进行的分类当然是任意的,但没关系,因为编程中的类型声明也是任意的。

  • 类型是数据如何在内存中布局的规范。这是我能想到的最底层的想法。在这种观点下,类型没有说明数据的目的或语义,而只说明计算机将如何构造、处理数据等。在这个想法中,类型更像是数据编码通信协议

您使用的类型的含义取决于您的域。正如已经暗示的那样,如果您是一名逻辑学家,正在研究如何证明程序的属性,那么第一个定义将比第三个定义更有用,因为数据布局(通常)与证明无关。如果您是硬件设计师或低级系统(如 CLR 或 JavaVM)的程序员,那么您需要第三个想法,而您并不真正关心第一个。但是对于只想继续完成任务的普通程序员来说,可能是中间那个适用。

于 2010-08-10T14:01:16.297 回答
3

在许多语言中,物理上的类型只存在于编译时。对于较旧的语言尤其如此。我猜 C 有这样的类型在程序运行时根本不存在于内存中。

在其他语言中——特别是那些允许运行时类型信息访问的语言(例如带有RTTI的 C++ ,或 C#,或任何动态语言,如 Python)——类型只是元数据。类型的二进制描述。你知道,如果你试图将数据序列化为二进制流,你会得到什么样的东西。

于 2010-08-10T13:49:21.130 回答
2

我会说恰恰相反。它是内存中位和字节的语言表示。

于 2010-08-10T13:48:46.030 回答
2

类型是关于位和字节的元数据,它定义了如何以有意义和安全的方式操作它们。

于 2010-08-10T13:57:21.640 回答
1

我想说类型可以有多种含义。

我倾向于更喜欢它作为接口约束的含义。(编写良好的目标代码将所有内存数据定义为私有)。

在这种情况下,类型绝对与内存表示无关。相反,它只是其成员方法的合同。

于 2010-08-10T13:51:02.140 回答
1

“类型”是一个集合,其成员(“对象”)具有离散的有限表示和一组有用的共享属性。

对象的实际内存表示不一定是类型定义的一部分。也就是说,单个对象可能有多个内存表示。重要的是对象可能不是无限的或模拟的。

类型的共享属性可以是任何东西。在面向对象的系统中,属性将包括(在低级别)数据和行为。事件通知也很常见。一些属性可能是有条件的而不违反类型定义(如果布尔属性 X 为真,则属性 Y 也存在),只要规则在类型中的所有对象之间保持一致即可。

“子类型”是其成员具有更广泛的共享属性集的类型的子集。

这种思考类型的方式与您在问题中提出的方式非常不同,我相信这种区别很重要。

如果将类型视为内存中的表示,那么该表示将被视为该类型的显着特征,并且将被视为理所当然。互操作将通过对现有字节序列的低级转换和重新解释来实现。在某些情况下,当该表示发生变化时,这可能会导致问题。

然而,如果人们根据属性来看待类型,那么从一种类型系统到另一种类型系统的转换将涉及相应对象之间数据字段的高级转换。对象是否兼容的确定将基于它们的显着属性,并且问题变得不太可能。

即使在互操作的世界中,也不应该依赖类型内部细节的知识。也就是说,不属于该类型定义的类型的实现的特性不应被当作该类型的一部分来使用。

于 2010-08-10T15:09:07.053 回答
0

IIRC 强类型语言在编译时强制执行对象类型,例如数字必须是 int、float 等类型。在弱类型语言中,您可以说 giraffe = 1 + frog * $100 / 'May 1' 并且类型在运行时被解析。而且您通常会遇到很多运行时错误。

在数据交换情况下(如 COM、CORBA、RPC 等),由于二进制兼容性(大端、小端)和格式(从一种语言传递到另一种语言时如何表示字符串和日期,每个使用不同的编译器?)。因此,编组尝试和解析每个参数的类型。ASN.1 是在机器之间交换数据时构建“通用类型”框架的众多尝试之一。

于 2010-08-10T13:53:07.123 回答
0

类型是人类可读的逻辑蓝图,用于说明数据应如何在内存中表示和组织。这是一种允许人类以标准方式将概念合理化为数字序列的方式。机器和编译器真的不关心字符串、整数、fooClass 之间的区别。这些“类型”只是简单地同意所有人类程序员将逻辑概念转换为内存中的合理数据结构的组织单元。

于 2010-08-10T13:54:08.127 回答
0

这取决于您正在使用的编程范例。在 OO 中,类型可以表示现实世界的对象,换句话说,计算机可以表示的现实世界对象的所有数据(或者您感兴趣的部分)。

于 2010-08-10T13:48:26.890 回答
0

类型是一个捆绑词。当你知道某物的类型时,你就知道它占用了多少内存,它的各个部分是如何存储的,但更重要的是你也知道你可以用它做什么。例如,有几种整数类型占用与指针相同的内存量。但是,您可以将一种整数类型乘以另一种(例如 3 乘以 4),但不能将两个指针相乘。您可以在具有 Foo 方法的某些用户定义类型(结构或类)上调用 Foo() 方法,例如编写 x.Foo() ,但您不能对不同的用户定义类型执行此操作没有 Foo 方法。您可以在某些类型对之间进行转换,但不能在其他类型之间进行转换,或者您可以将 A 转换为 B,但不能将 B 转换为 A。等等。在某些语言中,也有区别,例如它是否为 const。

编译器和运行时携带大量信息,所有这些信息加起来就是项目的类型。它占用多少字节的物理性(或任何其他你可以合理地声称是有形的东西)真的不是重点。

于 2010-08-10T13:54:53.157 回答