例如,在Java中,存在原始数据类型" int"它代表一个32位的值,并且有一个"整数"这只是一个单一的" int"财产(当然还有一些方法)。这意味着Java" Integer" class仍然在幕后使用原语。这就是Java不是纯粹的面向对象编程语言的原因。
如果没有原语,可以在哪里存储值?例如,我想象这个伪类:
class Integer
{
private Integer i = 12;
public Integer getInteger
{
return this.Integer;
}
}
这将是递归的。
如何在没有基元的情况下实现编程语言?
我感谢任何帮助解决我的困惑。
答案 0 :(得分:11)
在场景后面始终是原始的,因为它只是内存中的一点。但是有些语言隐藏了只能用于对象的原语。 Java允许您同时使用对象和基元。
答案 1 :(得分:4)
如果您的意思是primitives
值类型,那么您可以在没有它们作为用户的情况下生存并使用Integer
代替int
并支付堆分配的开销并{{1} 1}}。但这并不是免费的,你必须付出代价。像32位/ 64位整数和GC
这样的基元总是会更快,因为它们有硬件支持。
从编译器编写者的角度来看,你必须使用机器支持的东西才能使事情发挥作用。
答案 2 :(得分:3)
LISP是一种非常简单的功能语言。基本LISP没有原始int
,并且对整数的一个解决方案是successor of successor of successor of zero
为3。
这实际上有一些优点,整数是开放式的,没有溢出所以操作真的是可交换的,关联的等等。一些很好的优化可能。当然,succ(succ(succ(zero)))
可以用更多元组的方式编码(最好不要在LISP中编码)。
在后来的正常情况下,LISP'3'将是一个原子,123就是这样一个原子,带有数学运算符。
然后有符号操作语言(SNOBOL)可以对数字字符串['4', '0'] * ['3']
进行数学运算。
因此,名称是对象(原子),如char'a'或int 42。
答案 3 :(得分:3)
这可能有助于向您展示采用"所有内容都是对象的语言中的类似代码。设计原则比Java更严肃。即,Smalltalk。想象一下,如果Java只有int
,而不是Integer
,,,那么您曾经需要使用Integer
的所有内容都可以{{1} }}。这就是Smalltalk。
这是定义Squeak 5.0中int
类的代码的摘录:
SmallInteger
不要忘记语法或语义的细节。你应该得到的是:Integer immediateSubclass: #SmallInteger
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'Kernel-Numbers'!
!SmallInteger commentStamp: 'eem 11/20/2014 08:41' prior: 0!
My instances are at least 31-bit numbers, stored in twos complement
form. The allowable range in 32-bits is approximately +- 10^9
(+- 1billion). In 64-bits my instances are 61-bit numbers,
stored in twos complement form. The allowable range is
approximately +- 10^18 (+- 1 quintillion). The actual
values are computed at start-up. See SmallInteger class startUp:,
minVal, maxVal.!
!SmallInteger methodsFor: 'arithmetic' stamp: 'di 2/1/1999 21:31'!
+ aNumber
"Primitive. Add the receiver to the argument and answer with the result
if it is a SmallInteger. Fail if the argument or the result is not a
SmallInteger.
Essential, No Lookup. See Object documentation whatIsAPrimitive."
<primitive: 1>
^ super + aNumber! !
!SmallInteger class methodsFor: 'instance creation' stamp: 'tk 4/20/1999 14:17'!
basicNew
self error: 'SmallIntegers can only be created by performing arithmetic'! !
被定义为一个对象类,就像语言中的其他所有东西一样,算术运算就像语言中的其他代码一样。但这有点奇怪。它没有实例变量,你只能通过执行算术来创建实例,而且大多数方法看起来都是循环定义的。
&#34;在引擎盖&#34;下,实现将算法映射到适当的机器指令(SmallInteger
是对实现的暗示)并将<primitive: 1>
存储为什么都没有超过整数本身。相对于硬件而言,限制范围是因为保留了几个位来将记忆单词标记为整数,而不是指向对象的指针(&#34; tagged pointers&#34;)。
答案 4 :(得分:2)
最终无法在机器上(直接或间接)访问实际数据(例如,基元或实际位),它不再是编程语言,而是Interface Description Language。
答案 5 :(得分:1)
最终一切都回到内存中的位和计算机的指令。汇编程序,编译程序,程序,面向对象和所有其他东西之间的区别在于你和位之间有多少抽象,以及从抽象中获得多少好处(或成本)。
答案 6 :(得分:1)
(我将这个问题改为我相信你的问题。如果你认为我做错了,请随时发表评论。)
如果没有内在类型,那么基于组合和继承的类型系统如何定义任何有用的类型?除非语言实现知道至少一个内部类型开始,否则任何定义的类型都将注定是递归的或空的。这是不可避免的吗?
是的,在我所知道的每种C系列语言中,这几乎是不可避免的。
如果每种类型都由其他类型组成,那么至少,你需要有一个内在类型来构建 - 例如,一个代表位的内在类型,以便通过组合构建字节类型,然后是 word 类型,然后是各种整数类型,依此类推。然后,您需要通过操纵构成其内部表示的位来定义可以对这些类型执行的操作。
尽管您需要的只是一种内在类型,但它可能非常低效 - 您不想浪费空间或CPU周期而且您确实希望利用各种存储位置和目标架构提供的指令,包括FP寄存器和其他内容。
因此,在性能和&#34;纯度&#34;之间做出了很好的折衷。是用语言提供一些可能被现代CPU识别的内在类型(如 int32 , int64 , float , double 等)并在其上构建类型系统的其余部分。在Java中,他们决定将这些内在类型称为 primitives ,并将它们与类分开。