【发布时间】:2010-09-12 01:16:27
【问题描述】:
PowerShell 绝对属于动态语言的范畴,但它会被认为是强类型的吗?
【问题讨论】:
-
术语“强类型”没有定义。能否请您定义一下,以便客观地回答您的问题?否则每个人都会替换他们的自己的定义,我们最终会陷入一场巨大的火焰盛宴。
-
你的意思是:PowerShell是静态类型的吗?
PowerShell 绝对属于动态语言的范畴,但它会被认为是强类型的吗?
【问题讨论】:
如果你需要它可以。
像这样:
[1] » [int]$x = 5
[2] » $x
5
[3] » $x = 'haha'
Cannot convert value "haha" to type "System.Int32". Error: "Input string was not in a correct format."
At line:1 char:3
+ $x <<<< = 'haha'
[4] »
使用 [type] 符号表示您是否关心变量的强类型化。
编辑:
正如edg 指出的那样,这不会阻止 PowerShell 在执行 (5 + "5") 时将“5”解释为整数。我又挖了一点,根据 Windows PowerShell in Action 中的 Bruce Payette 的说法,PowerShell 实际上是一种“类型混杂的语言”。所以,我想,我的答案是“有点”。
【讨论】:
从技术上讲,它是一种强类型语言。
您可以拒绝在 shell 中声明类型,使其表现得像动态类型脚本语言,但它会将弱类型对象包装在“PsObject”类型的包装器中。通过使用“New-Object”语法声明对象,对象是强类型的而不是包装的。
$compilerParameters = New-Object System.CodeDom.Compiler.CompilerParameters
【讨论】:
我收回我之前的回答——引用如下。我应该说一些更细微的东西,比如:
PowerShell 具有强大的类型系统和强大的类型推断功能,并且是动态类型的。
在我看来,这里有几个问题在起作用,因此要求更好地定义“强类型语言”的含义的答案在解决问题时可能更明智。
由于 PowerShell 跨越了许多界限,因此关于 PowerShell 所在位置的答案可能存在于由以下区域组成的维恩图中:
“PowerShell 是一种强类型语言。
但是,它只需要你声明有歧义的类型。
如果它能够推断出一个类型,它不需要你指定它。”
【讨论】:
我认为您需要定义“强类型”的含义:
在计算机科学和计算机编程中,术语强类型用于描述编程语言对如何混合涉及具有不同数据类型的值的操作指定一个或多个限制的情况。反义词是弱类型。然而,在短暂的计算历史中,这些术语被赋予了如此广泛的含义,以至于通常很难在断章取义的情况下了解单个作者在使用它们时的含义。
【讨论】:
围绕术语存在一定程度的混淆。 This article 解释了一种有用的类型系统分类法。
PowerShell 是动态的、隐式类型的:
> $x=100
> $x=dir
无类型错误 - 变量可以在运行时更改其类型。这类似于Python、Perl、JavaScript,但不同于C++、Java、C# 等。
但是:
> [int]$x = 100
> $x = dir
Cannot convert "scripts-2.5" to "System.Int32".
因此,如果您愿意,它还支持显式类型的变量。但是,类型检查是在运行时而不是编译时完成的,所以它不是静态类型化的。
我看到有人说 PowerShell 使用 类型推断(因为您不必声明变量的类型),但我认为这是错误的说法。类型推断是在编译时进行类型检查的系统的一项功能(如 C# 中的“var”)。 PowerShell 只在运行时检查类型,因此它可以检查实际值而不是进行推理。
但是,有一些自动类型转换正在进行:
> [int]$a = 1
> [string]$b = $a
> $b
1
> $b.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String System.Object
所以 一些 类型是即时转换的。根据大多数定义,这将使 PowerShell 成为一种弱类型语言。它肯定比例如更弱。 Python(几乎?)从不即时转换类型。但可能不像 Perl 那样弱,它可以根据需要转换几乎任何东西。
【讨论】:
$obj.SetFlag("None") 隐式转换比$obj.SetFlag([Company.Example.Product.Data.Transfer.Enums.Flags]::None) 容易得多
我认为进一步研究将字符串添加到 Int 示例将为讨论提供更多的参考。什么被认为是动态类型转换?其中一个 cmets 中的某个人说,在这种情况下:
4 + "4"
"4" 变成一个 Int32。我根本不相信情况是这样的。相反,我相信中间步骤发生在命令更改为:
4 + [System.Convert]::ToInt32("4")
请注意,这意味着"4" 在整个过程中保持一个字符串。为了证明这一点,请考虑以下示例:
19# $foo = "4"
20# $foo.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String System.Object
21# 4 + $foo
8
22# $foo.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String System.Object
【讨论】:
PowerShell 是动态类型的,简单明了。它的创建者 Bruce Payette 如此描述它。
此外,如果有人参加过基本的编程语言理论课,他们就会知道这一点。仅仅因为有一个类型注释系统并不意味着它是强类型的。甚至类型注释的变量在强制转换期间也会动态地表现。任何允许您将字符串分配给变量并将其打印出来然后将数字分配给同一变量并使用它进行计算的语言都是动态类型的。
此外,PowerShell 是动态范围的(如果这里有人知道这意味着什么)。
【讨论】: