为什么在声明变量时必须指定数据类型?


41

在大多数编码语言(如果不是全部)中,您需要声明变量。例如在C#中,如果它是一个数字字段,则

int PhoneNumber

如果我用正常的英语,我不需要申报PhoneNumberint使用它。例如,如果我请朋友萨姆给我他的电话号码,我会说:

“山姆给我电话号码”

我不会说

“ Char(20)Sam给我int电话号码”

为什么我们必须完全指定数据类型?


83
那是因为英语具有隐式键入-所以yourPhoneNumber被隐式键入为PhoneNumber-人类也具有动态内存分配...;)
HorusKol 2016年

28
您和Sam知道电话号码由数字组成,您会惊讶地发现其中的字母。电脑没有,需要告知。
托尔比约恩Ravn的安德森

16
当我在电影中听到1-800-JIMBO这样的数字时,我的想法是:这个数字怎么样?Oo
Muru

103
您不应该将phoneNumber声明为int。在大多数编程语言中,这将删除前导零。
Aron_dc '16

25
@HorusKol:人类不仅具有动态内存分配,而且具有高度非保守的垃圾收集器……
左右离开

Answers:


79

在大多数编码语言(如果不是全部)中,您需要声明变量。

[…]

为什么我们必须完全指定数据类型?

这是两个独立的问题:

  • 为什么我们需要声明变量?
  • 为什么我们需要声明类型?

顺便提一句,两者的答案是:我们没有。

有许多静态类型的编程语言,您无需声明类型。编译器可以根据周围的上下文和用法来推断类型。

例如,在Scala中,您可以说

val age: Int = 23

或者你可以说

val age = 23

两者是完全等效的:编译器将从Int初始化表达式推断类型23

同样,在C♯中,您可以说这两个,它们的意思完全相同:

int age = 23;
var age = 23;

此功能称为类型推断,除了Scala和C♯之外,许多语言都具有此功能:Haskell,Kotlin,Ceylon,ML,F♯,C ++,您都可以命名。甚至Java也具有有限类型的类型推断。

在动态类型的编程语言中,变量甚至没有类型。类型仅在运行时动态存在,而不是静态存在。只有值和表达式才具有类型,并且只有在运行时变量才没有类型。

例如在ECMAScript中:

const age = 23;
let age = 23;

最后,在许多语言中,您甚至都不需要声明变量。例如在Ruby中:

age = 23

实际上,最后一个示例在多种编程语言中均有效。例如,完全相同的代码行也可以在Python中工作。

所以,

  • 即使在变量具有类型的静态类型语言中,也不必声明它们,
  • 在动态类型语言中,变量没有类型,因此显然您甚至不能声明它们,
  • 在许多语言中,您甚至不必声明变量

2
再加上一个用于解释类型推断和动态类型化(后期绑定)的内容
dcorking

36
这是有关问题背后误解的重要信息,但仍未解决问题。更正确的问题是,为什么在用语言声明变量时需要指定数据类型他们为什么设计方式?这个问题有很好的答案,在详细介绍替代方案的同时,拓宽了OP的视野,而且非常好,但对我而言,这似乎并不完整。
KRyan

7
@KRyan:如果您想知道为什么某个语言设计师做出了某种语言设计选择,恐怕您将不得不询问该语言设计师。我不能告诉你为什么C♯的设计师决定反对类型推断,也不能告诉你为什么他们后来改变了主意。语言设计是自以为是的,常常会让人感到厌恶。如果OTOH,您想了解所涉及的具体权衡,答案基本上是对Pierce教授的类型和编程语言重印,这对于Stack Exchange来说太宽泛了。
约尔格W¯¯米塔格

2
JörgWMittag:正如@KRyan所说的那样,答案“您不必”不是很有趣(这很明显-许多语言在某些情况下允许省略类型声明)。问题“为什么要声明类型”更加有趣,并且更好地反映了原始问题的精神(您的回答让我想起了一个笑话:“我们在哪里?”-“您在热气球中!”)。您不需要知道当时特定语言的设计师的想法,就可以提供一些支持类型声明的充分理由。
jfs

1
@Zaibis: auto i = 1 // i is inferred to type intvector<int> vec; auto itr = vec.iterator(); // itr is inferred to type vector<int>::iterator等等。如果您想知道它的工作原理,可以在规范中进行查找。
约尔格W¯¯米塔格

53

当您使用自然语言来引用信息时,它不是很精确,尤其是不会与他人就您的意图进行过多交流。尝试使用自然语言进行数学运算时也会发生类似的问题:不够精确。

编程很复杂;错误太容易出现。类型是检查系统的一部分,该系统旨在通过检测错误情况来防止程序处于非法状态。不同的语言使用不同的类型:某些语言在编译时大量使用类型来检测错误。几乎所有语言都有一些不兼容类型的概念,即运行时错误。通常,类型错误表示程序中存在某种错误。当我们允许程序继续执行但有错误时,我们可能会得到非常差的答案。我们更喜欢停止程序,而不是得到错误或错误的答案。

换句话说,类型表示对程序行为的约束。当约束通过某种机制强制执行时,可以提供保证。这样的保证限制了考虑程序所需的推理量,从而简化了程序员阅读和维护程序的任务。如果没有类型及其检测类型错误的工具(即编译器)的含义,那么编程负担会大大增加,因此成本也会更高。

确实,(许多)人类可以轻松区分欧洲,美国和国际电话号码。但是,计算机并没有真正“思考”,如果告诉他们,会拨打欧洲的美国电话号码,反之亦然。例如,类型是区分这些情况的好方法,而不必教计算机如何“思考”。在某些语言中,由于尝试在美国电话系统上混用欧洲电话号码,我们可能会遇到编译时错误。该错误告诉我们,在尝试运行程序之前,我们需要修改程序(可能是通过将电话号码转换为国际拨号序列,或者使用欧洲的电话号码)。

此外,由于计算机不认为,字段或变量的名称(例如phonenumber)对计算机没有任何意义。对于计算机,该字段/变量名称仅为“ blah123”。考虑一下如果所有变量均为“ blahxxx”,您的程序将如何。kes。好吧,这就是计算机所看到的。提供类型可以使计算机了解变量的含义,而变量的含义仅凭其名称是无法推断的。

此外,正如@Robert所说,在许多现代语言中,我们不必像过去那样指定类型,因为C#之类的语言执行“类型推断”,这是确定适当类型的一组规则用于上下文中的变量。C#仅提供对局部变量的类型推断,而不提供形式参数,类或实例字段的类型推断。


4
令人难过的部分:无法推断可公开访问的成员的类型(公共字段,公共方法签名),因为您无法预测何时以及如何使用它。另外,类型注释是文档。
塞尔吉奥·图伦采夫16'Mar

我认为您应该突出显示/粗体此行:Types are part of a system of checks that ...因为它直接回答了Why do we have to specify data type at all?..
txtechhelp

注意:您的回答假设,用于指定类型的语言在避免错误方面比常规编程语言更好。显然不是这样,例如,考虑使用图灵完备的C ++模板语言(并因此可以表达许多错误检查),但是与许多其他图灵完备的语言(例如Haskell,Python甚至其他语言)相比,它几乎是不可读的C ++本身。问问自己为什么不使用相同的编程语言来将错误检查表示为程序的其余部分(在某些情况下(但并非在所有情况下)都有很好的答案)。
jfs

@SergioTulentsev事实并非如此-在F#中,您可以拥有公共方法而无需显式指定其类型。编译器将从方法内部的用法推断类型。例如,以下是有效的公共方法定义:static member add x y = x + ymember x.Append s = x.Text + s。在第一种情况下,由于加法xy将被推断为int。在第二种情况下,根据类型的不同,它们将是有效的x.Text-如果为a string,则s也将为a string。我确实同意类型注释是文档。
Roujo

“隐式本地类型,显式接口类型”是许多人的编程方式,即使使用Haskell之类的语言,也允许您省略(几乎)所有类型,同时仍让编译器推断严格类型。当一种语言强制执行这种做法时(就像C#一样),很多人都不认为这很可悲。
2016年

29

除其他答案外,还应包含一件事。请记住,计算机只是位。说我给你的字节:

26 3A 00 FF

什么意思?它是通过计算机以这种方式存储的,但是没有任何解释,只是位。可以是4个ASCII字符。可以是整数。可能是数组中的一些字节。它可能是对象的一部分。它可能是指向该猫视频缓冲位置的指针。从汇编开始,几乎所有的编程语言都需要一些知识来知道如何解释这些位,以使它们进行有意义的计算。

而且由于计算机无法知道这些位的含义,因此需要您通过类型注释或其他答案中提到的类型推断机制来明确告知它们。


10
的确足够,但是要让您真正的头脑困惑,请意识到计算机永远无法理解这些位的含义,即使您告诉它更多的类型注释也是如此。您的解释只会变成更多的十六进制数字,以“澄清”第一个十六进制数字。意义是所有人创造的,目的是将意图放入电子设备中,并使他们按照我们的意图去做。现在去对工程师说“谢谢”。:)
通配符

1
我花了很多年在大型机上编程。对于PL / 1,这个答案很有意义。通常,我们将使用基于指针的基于存储的存储,该指针被设置为不同数据类型的另一个变量的地址,从而以不同的方式访问字节。例如PL / 1不支持1字节二进制数字字段,但是我们将在地址处使用1字符变量,以允许我们存储6字节数组,该数组存储6个单字节二进制字段(在这种情况下,允许我们保存每个地址6个字节-当存储空间昂贵时,这很重要)。
Kickstart

1
计算机能够理解很多可能性,但是即使是聪明的编译器也需要上下文来理解。它不是数字0或“ 0”。否则将在“ 5月1日”之前将字符串“ Dec 31”作为字符串进行排序,但如果将其作为日期则不进行排序。或取5/2。输入为2,但输入为2.5。同样,该类型是防止不必要转换的安全措施。Null,NaN和舍入或溢出也可能会成为问题。强和静态类型的语言具有一些优点。例如,编译器可帮助您在重构时检测问题。
Borjab

1
@Borjab您是说“ 2是整数 ”吗?
理查德·埃弗里特

1
@RichardEverett当然,那是一次lapsus。谢谢,但是迟到了编辑它。
Borjab

23

为什么计算机需要此信息的答案与数据表示有关

“数据类型”的名称是对规则的引用,这些规则可帮助计算机从计算机内存中的原始0和1原始状态存储和检索信息。

例如,您的常规8位ASCII字符将存储为计算机内存(RAM或磁盘)为01000001(大写字符“ A”,ASCII代码65)或00001000(百分号),或0和在这8位中为1。

再举一个例子,一些8位无符号整数可以存储为00000101(数字5)或00001000(数字8)

请注意,8和%字符的二进制表示形式可能是相同的,但是它们的含义不同,因为它们的类型不同。

即使是推断数据类型的语言,它们也可能没有规则“所有变量的类型都必须由程序员声明”,它们具有诸如“如果您的字符系列用引号括起来,则是字符串”之类的规则,并且每个数据类型还有更多规则。

因此,即使这些都需要数据类型才能理解0和1的含义,因此,例如,如果您尝试“加”两个字符,它们可以执行字符串连接功能;如果您要添加两个整数,则可以进行整数加法。

您的故事中,也可以说您没有询问Sam的电话号码,但是Sam给了您一张纸,上面写有“ 1123581321”。您不确定Sam是不是前八个斐波那契数字的粉丝,还是一个电话号码。要进行猜测,您必须考虑可用的上下文和提示,例如您可能是一天前向Sam询问了电话号码,或者便条上写着“给我打电话”,或者您是否在数数并找到它与大多数电话号码的格式匹配。只有到那时,您才知道这是您可以拨打的电话号码,而不是您要输入计算器的一些数字。

请注意,这些提示如何使您猜测该数字是电话号码,与这些提示如何引导一种不需要声明即可推断出值类型的计算机语言类似。


3
这是最接近的答案。这都与内存有关。您声明类型,以便编译器知道应用程序在运行时应请求多少内存。知道如何解释位是次要的。
Greg Burghardt

@GregBurghardt是的。为了使已经存在的位有意义,并在根据数据类型将给定数据转换为二进制后将这些位放在第一位。
Peeyush Kushwaha

10

在某些语言中,您不必指定数据类型。

支持类型推断的语言通常可以从您的用法中找出数据类型。例如,

var name = "Ali"

在内部键入为字符串,因为该值用引号引起来。

某些语言也不要求您声明变量。该变量在首次使用时创建。但是,出于多种重要原因,最好是专门声明变量的最佳实践。主要是因为做得更好可以表达您的意图。


5
var name = "Ali"实际上,这种样式对于现代静态类型的语言很常见。在静态类型语言中,类型在创建时是固定的,但仍可以由初始化程序确定。动态类型语言的定义是类型附加到值,而不是变量。因此,为变量分配值也可以设置变量的类型。
MSalters '16

@MSalters:我对措辞做了些微调整。
罗伯特·哈维

5
具有讽刺意味的是,这包括具有这种确切语法的C#。
德里克·埃尔金斯

1
@MSalters 因此,为变量分配值也可以设置变量的类型。或者该变量没有固有类型,并且解释器将尝试对变量的值进行任何运算。是否存在任何动态类型化的语言,var x = 5; x = "";因为第一个语句导致x与“ Number”类型相关联,因此不允许使用以下代码(Javascript)x?与动态类型冲突。如果不是,那么与变量关联的类型除了与值关联的类型以外,还有什么作用?
Zev Spitz

1
@ZevSpitz:第一种系统不是动态输入的,但根本没有输入。您的Javascript示例不是动态键入的,正是因为Number类型无法更改。在动态类型语言中,x = "";将x 的类型更改为字符串,即使以前是数字也是如此。
MSalters '16

9

因为那是语言设计所指定的。因此,要回答您的问题,我们需要查看使用C#和C ++等语言进行显式键入的意图。(好吧,C#之所以这样做,是因为C ++是因为C来做到这一点,所以我们需要回顾一下当时的意图)。

首先,显式和静态类型提供了严格的编码-将变量指定为整数意味着将变量或字符串分配给变量时,编译器和软件应感到惊讶并抛出错误。动态类型输入可能会给那些粗心的人带来麻烦(只需看一下PHP或javascripts处理数组和空字符串之类的事实的方法)。

您可以使用静态类型进行隐式键入-将变量初始化为字符串意味着变量应该只能是字符串,但是我的感觉是,这可能会给人类阅读代码带来麻烦(我倾向于假设在使用隐式键入时使用动态类型) )。

同样,在某些语言中,可以编写如下这样的伪代码来初始化来自字符串输入的类:

PhoneNumber phoneNumber = "(61) 8 8000 8123";

其次,显式类型也与内存分配紧密结合。一个int总是那么多字节。一个电话号码太多字节。编译器可以分配适当大小的内存块,然后在以后使用该内存块,而不必查看分配值时需要多少空间。

PhoneNumber phoneNumber;
...
phoneNumber = "some value from somewhere";

最后,它消除了混乱...是123是整数还是无符号整数?它们需要相同数量的字节,但是存储在这两种类型的变量中的最大值都大不相同...

并不是说显式要比隐式好,但是语言设计依赖于这类选择,而C#在隐式类型上的工作方式有所不同。PHP和javascript与显式键入的工作方式有所不同。


5

因为Sam比编译器聪明。例如,当您说给我电话号码时,您无需指定是否要输入国家/地区前缀或区号,而只需要最后4位数字的电话号码即可。另外,如果您要求提供当地披萨店的编号,您将可以回答“ pizza4u”。

山姆,从上下文中弄清楚了。尽管编译器也可以从上下文中找出问题,但Sam会做得更好(并且能够打断要求澄清的过程)。

有两种类型和变量的基本方法,一种是变量具有类型,在这种情况下,类型不允许的操作被禁止并阻止编译,或者值具有类型和变量不允许的操作。类型在运行时捕获。

每种方法都有其优点和缺点。通常,编译器作者会尝试最小化缺点并最大化优点。例如,这就是为什么C#允许var phoneNumber = GetPhoneNumber();并将从GetPhoneNumber的签名推断出phoneNumber的类型的原因。这意味着您必须声明方法的类型,而不是声明接收结果的变量。另一方面,针对javascript有各种类型的提示/强制项目。一切都是权衡。


3

这取决于数据的存储方式。如果您要与Sam互动,可以做一个更好的比较,以便您可以写下来,但纸上只有八个字符。

“山姆,给我电话号码。”

“ 5555555555”

“哦,不,我没纸了。如果我能提前知道要多少数据,我本可以准备得更好!”

因此,大多数语言使您声明一个类型,以便它会提前知道并准备:

“山姆,电话号码多久?”

“十个字符。”

“好吧,那就让我拿张大纸吧。现在给我手机号码。”

“ 5555555555”

“知道了!谢谢山姆!”

当您查看数据的实际基本存储方式时,它变得更加毛茸茸。如果您像我一样,则有一个笔记本,上面有杂项笔记,数字被涂了字迹,没有任何上下文或标签,也不清楚三天后的含义。这也是很多时候计算机的问题。许多语言都有“ int”类型(int,long,short,byte)和“ float”(浮点,双精度)类型。为什么有必要?

首先,让我们看一下如何存储整数,并且该整数通常在计算机中表示。您可能已经知道,在基本级别上,它们都是二进制的(1和0)。二进制实际上是一个数字系统,其工作方式与我们的十进制数字系统完全相同。以十进制表示,从0到9计数(没有写的无限的隐含前导零),然后滑回到0并递增下一个数字,这样就得到10。重复直到从19滑到20,重复进行,直到从99滚动到100,依此类推。

二进制没有什么不同,除了不是0到9,而是0到1。0、1、10、11、100、101、110、111、1000。因此,当您输入9时,以二进制记录的内存为1001。这是实际数字。可以完全按照这种形式对其进行加,减,乘等操作。10 + 1 =11。10+ 10 = 100(将1滚动到0并携带1)。11 x 10 = 110(相当于11 + 11 = 110)。

现在,在实际的存储器(包括寄存器)中,有一个列表,数组(无论您要调用什么),位(可能为1或0')彼此相邻,这就是如何按逻辑方式将这些位组织成一个大于1的数字。问题是,如何处理小数?您不能只在寄存器的两个位之间插入硬件,而在每对位之间添加“十进制位”会花费太多的时间。那么该怎么办?

您对其进行编码。通常,CPU或软件的体系结构将确定如何完成此操作,但是一种常见的方法是在寄存器的第一位尾数中存储一个符号(+或-,通常为1为负)。(移位的数字)但是对于接下来的X个位数,很多时候需要去掉小数),而对于其余的位数,则需要一个指数(必须移位它的次数)。这类似于科学记数法。

通过键入,编译器可以知道它在看什么。想象一下,您将值1.3存储在寄存器1中。在这里,我们将提出自己的特殊编码方案,1位表示符号,4表示尾数,3表示指数(1表示符号,2表示幅度)。这是一个正数,因此符号为正(0)。我们的尾数为13(1101),指数为-1(101(负数为1,01 = 1))。因此,我们将01101101存储在寄存器1中。现在,我们没有键入此变量,因此当运行时使用它时,它会说“确定,这是一个整数,为什么不这样做”,因此当它打印值时,我们看到109(64 32 + 8 + 4 + 1),这显然是不对的。

但是,并非每种语言都要求您显式键入。C#具有关键字“ var”,该变量导致在编译时解释变量的类型,而诸如Javascript之类的其他语言则是完全动态键入的,以至于您可以将整数存储在变量中,然后将其分配给布尔值,然后再次将其分配给字符串,语言将对其进行跟踪。

但这在编译器,解释器或运行时上要容易得多,并且通常会导致程序更快,因为它不必花费宝贵的资源来对所有类型进行排序—询问您,程序员,哪种您提供的数据。


2

在某些编程语言中,您不必声明变量的数据类型。甚至在某些编程语言中,您也不必事先声明变量。您可以立即使用它们。

不声明变量名的麻烦在于,如果您不小心拼错了变量名,那么现在您将不小心创建了一个新的,完全不相关的变量。所以,当你运行你的程序,你不能明白,为什么地狱变量设置了突然有什么也没有......直到几个小时的调试后,你意识到你键入的名字该死的错!RR!

因此他们做到了,因此您必须事先声明要使用的变量名。现在,当您输入错误的名称时,您将得到一个编译时错误,该错误会在程序甚至运行之前立即告诉您错误的确切位置。那不是那么容易吗?

同样处理数据类型。在某些编程语言中,您不必声明事物应该是什么类型。如果您的customer变量实际上只是一个客户的名字,而不是整个客户对象,则尝试从一个普通的普通字符串中获取客户地址……将不起作用。静态类型的全部要点是程序将无法编译。它会大声抱怨,指出问题所在的确切位置。这比运行代码并试图弄清楚为什么它无法正常工作快得多。

所有这些功能都可以告诉编译器您打算做什么,因此它可以检查您实际做了什么并确保它有意义。这使编译器可以为您自动定位错误,这很重要。

(回溯到遥远的过去,您不必声明子例程。您只需声明GOSUB特定的行号。如果要在子例程之间传递信息,则可以设置特定的全局变量,调用子例程,然后检查其他子例程。子例程返回时返回变量,但是这使得忘记初始化其中一个参数非常容易,因此现在几乎所有现代编程语言都要求您声明子例程采用的实际参数,因此我们可以检查是否已全部指定了它们。 )


1
在C ++中,您可以输入“ auto x = 1”,它知道它是一个整数。自动y = 1.2; auto z ='Z'; 等
QuentinUK '16

@QuentinUK在C#中,您可以输入var x=1类似的结果。但这没什么。在Haskell中,您可以编写完全没有类型签名的整个程序,但是它们都是静态类型的,并且如果您犯了错误,仍然会出错...(尽管不完全是主流。)
MathematicalOrchid

@QuentinUK但是,如果您编写for (auto i=0; i<SomeStdVector.size(); ++i)您的lint 会抱怨,因为它推导出了有符号类型,然后您将其与无符号类型进行比较。您必须编写auto i=0ul(再次明确输入类型信息,因此应该size_t i=0首先编写)。
dmckee

1

如果我使用的是普通英语,则无需将PhoneNumber声明为int即可使用它。例如,如果我请朋友萨姆给我他的电话号码,我会说:

“山姆给我电话号码”

我不会说>

“ Char(20)Sam给我int电话号码”

为什么我们必须完全指定数据类型?

流行到MathOverflow理论计算机科学和阅读一段时间才能得到的人类如何沟通与另一个算法的时候,他们希望确保没有误解的可能性的想法。或阅读一些成熟的编程语言的标准。

你会发现,定义什么类型的值被允许的一个术语真正的精确通信的一部分,甚至练习的人对人。

您已经注意到,日常交互相当正常,人类非常容错,因此,通过共享参与者的知识,通常可以避免对电话号码的误解。

但是,您是否曾经尝试删除另一个国家/地区某人的电话号码?他们是否明确告诉过您多少次将零推到国际地址?他们有没有告诉你他们的国家代码?你有这样认识吗?您期望多少位数?你得到了多少?您知道如何将数字分组吗?甚至如果分组有什么意义?

突然,问题变得更加棘手,您可能需要花费更多的精力来明确检查所接收的号码是否已理解发件人的意思。


0

声明类型的另一个原因是效率。尽管整数可以存储在1个字节,2个字节或4个字节中,但使用大量变量的程序可能会使用所需内存的4倍,具体取决于执行的操作。只有程序员知道较小的存储空间是否可行,因此他可以通过声明类型来声明。

同样,动态类型化的对象可以动态地允许许多可能的类型。与始终使用一种类型的程序相比,这可能会在“幕后”上产生一些开销,从而降低程序速度。


0

许多早期的编程语言(尤其是Fortran)不需要您在使用前声明变量。

这导致了许多问题。一个非常明显的事实是,编译器不再能够可靠地捕获简单的印刷错误。如果您有应该修改现有变量的代码,但有错别字,那么您仍然拥有完全合法的代码,它们只是创建了一个新变量(并为其分配了值):

longVariableName = 1

// ...

longVaraibleName = longvariableName + anotherLongVariableName

现在,孤立地看待这个问题,我已经提到过错别字是问题的根源,在这里找到错别字和问题可能很容易。在一个很长的程序中,它被埋在许多其他代码的中间,因此容易遗漏。

即使当前使用许多动态类型的语言,您仍然可以很容易地获得相同的基本问题。有些人有一些设施可以警告您是否将变量赋给您,但从未读过(启发式地捕获了很多这样的问题),其他人都没有。


0

当声明任何变量时,会在内存中分配一些空间,但是机器(在本例中为计算机)尚不知道必须为该变量分配多少空间。

示例:-您创建了一个程序,要求用户输入任何数字,在这种情况下,您必须指定一种数据类型来存储该数字,否则机器无法自行判断应该分配2个字节 还是 ,如果尝试, 2 GB的数据另一方面,如果您在程序中指定数据类型,则在编译之后,计算机将根据需要分配适当的空间。


在先前的11个答案中所提出和解释的观点上,这似乎没有提供任何实质性内容
t

1
na,您应该再次仔细阅读所有答案,并看到我已尝试以一种更容易理解的简单方式回答这个问题。
Atul170294 '16

我只是重新检查三人在此之前的一个发布一个小时左右,大部分最近的答案,这三个似乎正在同一点,每个我的阅读解释它以简单的方式比这里
蚊蚋

虽然我没有回应的奖励你的投票,但我想你应该知道一件事,,你应该downvote的答案,因为它可能给无用的或错误的信息,并且它是否包含任何进攻。具有最有用和最相关信息的所有答案将获得更高的投票数,足以区分答案,好答案和最佳答案。您幼稚的在没有任何充分理由的情况下拒绝回答的幼稚活动只会阻止其他人也希望分享他们认为可能对其他人有用的观点
Atul170294 2016年

1
您的答案很可能被否决了,因为它是不正确的。不需要静态类型来帮助进行内存管理。有许多语言允许动态键入,并且这些语言/环境能够处理您提到的内存管理问题。
杰伊·埃尔斯顿
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.