静态/动态与强/弱
静态/动态和强/弱类型之间有什么区别?
What is the difference between Static/Dynamic and Strong/Weak typing?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
静态/动态和强/弱类型之间有什么区别?
What is the difference between Static/Dynamic and Strong/Weak typing?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(11)
静态/动态类型与何时获取类型信息有关(在编译时或运行时)
强/弱类型是关于严格程度类型是区分的(例如,语言是否尝试从字符串到数字进行隐式转换)。
有关更多详细信息,请参阅wiki 页面。
Static/Dynamic Typing is about when type information is acquired (Either at compile time or at runtime)
Strong/Weak Typing is about how strictly types are distinguished (e.g. whether the language tries to do an implicit conversion from strings to numbers).
See the wiki-page for more detailed information.
您发现了业余爱好者用来谈论编程语言的术语的一个弱点。
不要使用术语“强”和“弱”类型,因为它们没有普遍认可的技术含义。相比之下,静态类型意味着程序在执行之前会被检查,并且程序可能在启动之前被拒绝。 动态类型意味着值的类型在执行期间被检查,并且类型错误的操作可能会导致程序停止或以其他方式在运行时发出错误信号。静态类型的主要原因是排除可能存在此类“动态类型错误”的程序。
强类型通常意味着类型系统没有漏洞,而弱类型意味着类型系统可以被破坏(使任何保证失效) 。这些术语经常被错误地用来表示静态类型和动态类型。
要了解其中的差异,请考虑 C:该语言在编译时进行类型检查(静态类型),但存在大量漏洞;您几乎可以将任何类型的值转换为相同大小的另一种类型——特别是,您可以自由地转换指针类型。 Pascal 是一种旨在强类型的语言,但众所周知,它有一个不可预见的漏洞:没有标签的变体记录。
随着时间的推移,强类型语言的实现经常会出现漏洞,通常使得运行时系统的一部分可以用高级语言来实现。例如,Objective Caml 有一个名为
Obj.magic
的函数,它具有简单返回其参数的运行时效果,但在编译时它将任何类型的值转换为任何其他类型之一。我最喜欢的例子是 Modula-3,其设计者将其类型转换构造称为“LOOPHOLE”。话虽如此,你不能指望任何两个人以完全相同的方式使用“强”和“弱”这两个词。所以避开他们。
You have discovered a soft spot in the terminology that amateurs use to talk about programming languages.
Don't use the terms "strong" and "weak" typing, because they don't have a universally agreed on technical meaning. By contrast, static typing means that programs are checked before being executed, and a program might be rejected before it starts. Dynamic typing means that the types of values are checked during execution, and a poorly typed operation might cause the program to halt or otherwise signal an error at run time. A primary reason for static typing is to rule out programs that might have such "dynamic type errors".
Strong typing generally means that there are no loopholes in the type system, whereas weak typing means the type system can be subverted (invalidating any guarantees). The terms are often used incorrectly to mean static and dynamic typing.
To see the difference, think of C: the language is type-checked at compile time (static typing), but there are plenty of loopholes; you can pretty much cast a value of any type to another type of the same size---in particular, you can cast pointer types freely. Pascal was a language that was intended to be strongly typed but famously had an unforeseen loophole: a variant record with no tag.
Implementations of strongly typed languages often acquire loopholes over time, usually so that part of the run-time system can be implemented in the high-level language. For example, Objective Caml has a function called
Obj.magic
which has the run-time effect of simply returning its argument, but at compile time it converts a value of any type to one of any other type. My favorite example is Modula-3, whose designers called their type-casting constructLOOPHOLE
.Having said that, you can't count on any two people using the words "strong" and "weak" in exactly the same way. So avoid them.
简而言之:在静态类型语言中,类型是静态,这意味着一旦将变量设置为类型,就无法更改它。这是因为类型与变量相关联,而不是与它引用的值相关联。
例如,在 Java 中:
而在动态类型语言中,类型是动态,这意味着在将变量设置为类型后,您可以更改它。这是因为类型与值而不是变量相关联。
例如在Python中:
另一方面,语言中的强/弱类型与隐式类型转换相关(部分取自@Dario的答案):
例如在Python中:
而在PHP中:
静态type 允许在编译时检查类型的正确性。静态类型语言通常是编译的,动态类型语言是解释的。因此,动态类型语言可以在运行时检查类型。
Simply put it this way: in a statically typed language the type is static, meaning once you set a variable to a type, you CANNOT change it. That is because typing is associated with the variable rather than the value it refers to.
For example in Java:
Whereas in a dynamically typed language the type is dynamic, meaning after you set a variable to a type, you CAN change it. That is because typing is associated with the value rather than the variable.
For example in Python:
On the other hand, the strong/weak typing in a language is related to implicit type conversions (partly taken from @Dario's answer):
For example in Python:
whereas in PHP:
Static typing allows for checking type correctness at compile time. Statically typed languages are usually compiled, and dynamically typed languages are interpreted. Therefore, dynamicly typed languages can check typing at run time.
弱类型意味着对象的类型可以根据上下文而改变。例如,在弱类型语言中,如果向字符串“123”添加另一个数字,则该字符串可能会被视为数字 123。弱类型语言的例子有 bash、awk 和 PHP。
另一种弱类型语言是 C,其中内存地址处的数据可以通过强制转换被视为不同的类型。
在强类型语言中,对象的类型不会改变 - int 始终是 int,尝试将其用作字符串将导致错误。 Java 和 Python 都是强类型的。
动态类型和静态类型之间的区别在于强制执行类型规则的时间。在静态类型语言中,每个变量和参数的类型都必须在源代码中声明,并在编译时强制执行。在动态类型语言中,仅在运行时使用类型时才检查类型。所以Java是静态类型的,而Python是动态类型的。
然而,界限有时可能有点模糊。例如,尽管 Java 是静态类型的,但每次使用反射或强制类型转换(例如,使用对象容器时),都会将类型检查推迟到运行时。
类似地,大多数强类型语言仍然会自动在整数和浮点数之间进行转换(在某些语言中是任意精度的 BigInt)。
Weak typing means that the type of an object can change depending on context. For example in a weakly typed language the string "123" may be treated as the number 123 if you add another number to it. Examples of languages with weak typing are bash, awk and PHP.
Another kind of weakly typed language is C, where the data at a memory address can be treated as a different type by casting.
In a strongly typed language the type of an object does not change - an int is always an int and trying to use it as a string will result in an error. Both Java and Python are strongly typed.
The difference between dynamic and static typing is when the type rules are enforced. In a statically typed language the type of every variable and parameter must be declared in the source and is enforced at compile time. In a dynamically typed language the types are only checked when they are used at runtime. So Java is statically typed and Python is dynamically typed.
However the boundaries can be a little blurry at times. For example although Java is statically typed, every time you use reflection or a cast (e.g. when using containers of Objects) they you are deferring the type check to runtime.
Similarly most strongly typed languages will still automatically convert between integers and floats (and in some languages abitrary precision BigInts).
今天研究这个主题时,我发现了这篇很棒的文章 http://blogs.perl.org/users/ovid/2010/08/what-to-know-before-debating-type-systems.html 它为我澄清了很多事情,我想它可能会增加上面一些很好的答案。
强类型和弱类型:
静态和动态类型
显式/隐式类型:
Today researching about this subject I came across this great article http://blogs.perl.org/users/ovid/2010/08/what-to-know-before-debating-type-systems.html It cleared up a lot of things for me and I thought It may add to some of the great answers above.
Strong and Weak Typing:
Static and Dynamic Types
Explicit/Implicit Types:
从 Scott 的编程语言语用学,第 3 版第 291 页,我们有
所以简单来说,静态/动态类型指的是类型检查发生的时间:静态类型的编译时间,动态语言的运行时间。同样,强/弱类型指的是一种语言在强制执行其类型系统方面的积极程度。
我试图将斯科特的描述翻译成一个漂亮的图表,我将其发布在下面。
From Scott's Programming Language Pragmatics, 3rd edition page 291, we have
So in simple terms, static/dynamic typing refers to the time when type checking occurs: compile time for static typing, and run time for dynamic languages. Likewise, strong/weak typing refers to how aggressive a language is in enforcing its type system.
I've tried to translate Scott's description into a nice diagram, which I've posted below.
静态与动态类型语言
静态地
强类型语言与弱类型语言
很好的进一步阅读
Statically v/s dynamically typed languages
Strongly v/s weakly typed languages
Good further readings
在编程中,数据类型是一种分类,它告诉变量将保存什么类型的值,以及可以对这些值执行哪些数学、关系和逻辑运算而不会出错。
在每种编程语言中,为了最大限度地减少出错的机会,都会在程序执行之前或期间进行类型检查。 根据类型检查的时机,编程语言分为两种类型:静态类型和动态类型语言。
另外,根据隐式类型转换是否发生,编程语言有两种类型:强类型和弱类型语言。
静态类型:
类型检查在编译时完成
在源代码中,在变量声明时,必须显式指定该变量的数据类型。因为如果在源代码中指定了数据类型,那么在编译时源代码将转换为机器代码并且可以进行类型检查
这里数据类型与变量关联,例如,
int计数。并且这种关联是静态的或固定的
如果我们尝试通过分配其他数据类型的值(
int count = "Hello "
) 进入它,然后我们会得到错误如果我们尝试通过使用其他数据类型(
boolean count
)重新声明已声明的变量(int count
)来更改数据类型,那么我们也会 得到错误得到错误As type检查和类型错误检测是在编译时完成的,这就是为什么在运行时不需要进一步的类型检查。因此程序变得更加优化,执行速度更快
如果我们想要更严格的代码,那么选择这种类型的语言是更好的选择
示例:Java、C、C++、Go、Swift 等
动态类型:
类型检查在运行时完成
在源代码中,在变量声明时,不需要显式指定该变量的数据类型。因为在运行时进行类型检查时,语言系统根据分配给该变量的值的数据类型来确定变量类型
这里数据类型与分配给变量的值相关联,例如,
var foo = 10
, 10 是一个数字,所以现在 foo 是数字数据类型。但这种关联是动态的或灵活的我们可以通过分配其他数据类型的值(
foo = " Hi"
) 进去,没有错误我们可以通过使用其他数据类型的值重新声明它 (
var foo = true
) 来轻松更改已声明变量 (var foo = 10
) 的数据类型 (var foo = true
) >),没有错误由于类型检查和类型错误检测是在运行时完成的,这就是为什么程序变得不太优化,导致执行速度变慢的原因。尽管这些类型的语言如果实现 JIT 编译器,执行速度会更快
如果我们想轻松编写和执行代码,那么这种类型的语言是更好的选择,但在这里我们可能会遇到运行时错误
示例:Python、JavaScript、PHP、Ruby 等
强类型:
数据类型相关规则和限制严格维护
从一种数据类型到另一种数据类型的转换必须显式完成< /strong>,没有隐式类型转换
可以在编译时或运行时进行类型检查。这意味着强类型语言可以是静态类型的,也可以是动态类型的
示例:Python、Java、Ruby、C# 等
弱类型:
数据类型相关规则和限制松散维护
从一种数据类型到另一种数据类型的转换可以隐式发生
如果我们在两个不匹配的数据类型的值之间执行某些操作,那么这种类型的语言可能不会抛出错误。相反,弱类型语言将应用自己的隐式类型转换规则并返回一些结果
类型检查可以在编译时或运行时完成。这意味着弱类型语言可以是静态类型的,也可以是动态类型的
示例:JavaScript、C、C++、PHP 等
In Programming, Data Type is a Classification which tells what type of value a variable will hold and what are the mathematical, relational and logical operations can be done on those values without getting error.
In each programming language, to minimize the chance of getting error, type checking is done either before or during program execution. Depending on the Timing of Type Checking, programming languages are 2 types : Statically Typed and Dynamically Typed languages.
Also depending on whether Implicit Type Conversion happens or not, programming languages are 2 types : Strongly Typed and Weakly Typed languages.
Statically Typed :
Type checking is done at compile time
In source code, at the time of variable declaration, data type of that variable must be explicitly specified. Because if data type is specified in source code then at compile time that source code will be converted to machine code and type checking can happen
Here data type is associated with variable like,
int count
. And this association is static or fixedIf we try to change data type of an already declared variable (
int count
) by assigning a value of other data type (int count = "Hello"
) into it, then we will get errorIf we try to change data type by redeclaring an already declared variable (
int count
) using other data type (boolean count
) then also we will get errorAs type checking and type error detection is done at compile time that's why during runtime no further type checking is needed. Thus program becomes more optimized, results in faster execution
If we want more rigid code then choosing this type of language is better option
Example : Java, C, C++, Go, Swift etc.
Dynamically Typed :
Type checking is done at runtime
In source code, at the time of variable declaration, no need to explicitly specify data type of that variable. Because during type checking at runtime, the language system determines variable type from data type of the assigned value to that variable
Here data type is associated with the value assigned to the variable like,
var foo = 10
, 10 is a Number so now foo is of Number data type. But this association is dynamic or flexiblewe can easily change data type of an already declared variable (
var foo = 10
), by assigning a value of other data type (foo = "Hi"
) into it, no errorwe can easily change data type of an already declared variable (
var foo = 10
), by redeclaring it using value of other data type (var foo = true
), no errorAs type checking and type error detection is done at runtime, that's why program becomes less optimized, results in slower execution. Although execution of these type of languages can be faster if they implement JIT Compiler
If we want to write and execute code easily then this type of language is better option, but here we can get runtime error
Example : Python, JavaScript, PHP, Ruby etc.
Strongly Typed :
Data type related rules and restrictions are Strictly maintained
Conversion from one data type to another data type must be done explicitly, no implicit type conversion
type checking may be done at compile time or runtime. It means strongly typed languages can be either statically typed or dynamically typed
Example : Python, Java, Ruby, C# etc.
Weakly Typed :
Data type related rules and restrictions are Loosely maintained
Conversion from one data type to another data type can occur implicitly
If we perform some operation between values of two mismatched data types then this type of language may not throw error. Instead weakly typed languages will apply their own rules for implicit type conversion and will return some result
type checking may be done at compile time or runtime. It means weakly typed languages can be either statically typed or dynamically typed
Example : JavaScript, C, C++, PHP etc.
我认为其他同事做得很好,尤其是。解释静态类型和动态类型之间的区别。但就强类型和弱类型来说,应该说是有的
不同的理解/观点。
这里有两个例子:
有人说 Haskell 是强类型的,因为你不被允许进行任何类型转换。
其他人(例如 Dario 的观点)说,一种允许故意从字符串隐式转换为数字的语言是弱类型的,但甚至其他人也称这只是鸭子类型。
这两种说法都强调的不是类型系统的相反极端,而是完全不同的方面。所以我同意拉姆齐先生的观点,不要使用“强”和“弱”这两个术语来区分类型系统。
I think the other colleagues made a good job esp. explaining the difference between static and dynamic typing. But as far as strong and weak typing is concerned, it should be said that there are
different understandings/views.
Here two examples:
Some say that Haskell is strongly typed, because you are not allowed to make any type conversions.
Others (e.g. Dario's view) say a language that allows to implicitly convert from string to number on purpose is weakly typed, but even others call this just duck typing.
Both statements highlight not the opposite extremes of a type system, but completely different aspects. So I join Mr. Ramsey's view not to use the terms "strong" and "weak" to distinguish between type systems.
来自 Addison Wesley,《面向对象的分析和应用程序设计》,第 3 期,第 66 页:
From Addison Wesley, Object Oriented Analysis and Design with Applications, 3rd, page-66:
静态类型语言通常要求声明变量的类型,然后在编译时检查以减少错误。 “静态类型”中的“静态”一词指的是“静态代码分析”,即在执行代码之前检查代码的过程。尽管静态类型语言可以从表达式或实际参数的右侧推断变量的类型,但实际上大多数静态类型语言都需要显式声明变量类型。
动态类型语言通常不要求变量声明具有类型,并且它们根据计算每个赋值语句的右侧或函数调用的实际参数而计算出的类型来推断变量类型。由于变量在其生命周期内可以被多次赋值,因此它的类型可以随着时间的推移而改变,这就是它被称为“动态类型”的原因。此外,运行时环境需要跟踪每个变量的当前类型,因此类型绑定到值而不是变量声明。这可以被认为是运行时类型信息(RTTI)系统。
静态和动态类型语言的元素可以组合。例如,C# 支持静态和动态类型变量,面向对象语言通常支持类型层次结构的向下转换。静态类型语言通常提供各种绕过类型检查的方法,例如使用强制转换、反射和动态调用。
强类型与弱类型是指语言试图防止由于使用变量而导致错误的连续体,就好像它是一种类型,而实际上它是另一种类型。例如,C 和 Java 都是静态类型语言,但是 Java 使用比 C 更强的类型检查。以下 C 代码很容易编译和运行,并且会在运行时将随机值放入变量 b 中,很可能会导致bug:
等效的 Java 代码会产生编译错误,这通常是更好的选择:
Statically typed languages generally require you to declare the types of variables, which is then checked at compile time to reduce errors. The word "static" in "statically typed" refers to "static code analysis", which is the process of examining the code prior to executing it. Although it is possible for a statically typed language to infer the type of the variable from the right hand side of an expression or actual parameters, in practice most statically typed languages require variable types to be explicitly declared.
Dynamically typed languages generally do not require variable declarations to have types, and they infer variable types based on the type calculated as a result of evaluating the right hand side of every assignment statement or the actual parameters to a function call. Since the variable can be given multiple assignments over its lifetime, its type can change over time and this is why it is called "dynamically typed". Also, the runtime environment needs to keep track of the current type for each variable, so the type is bound to the value rather than with the variable declaration. This can be considered a runtime type information (RTTI) system.
Elements of statically and dynamically typed languages can be combined. For example, C# supports both statically and dynamically typed variables, and object oriented languages generally support down-casting the type hierarchy. Statically typed languages usually provide various ways to bypass type checking, for example by using casting, reflection and dynamic invocation.
Strong vs. Weak Typing refers to a continuum of how much the language tries to prevent bugs due to using a variable as if it were one type when it is in fact another type. For example both C and Java are statically typed languages, however Java uses much stronger type checking than does C. The following C code is happy to compile and run, and will put a random value into the variable b at runtime, most likely causing a bug:
The equivalent Java code will produce a compile error, which is generally preferable: