PowerShell是一种强类型语言吗?

16

PowerShell 明显属于动态语言,但是否被认为是强类型语言呢?


3
“strongly typed” 这个术语没有定义。请问你能否定义一下它,这样你的问题才能得到客观的回答。否则每个人都会用自己的定义来替代它,我们最终将陷入一场大规模的争论。 - Jörg W Mittag
你的意思是:PowerShell 是静态类型的吗? - Kellen Stuart
7个回答

28

术语方面存在一定的混淆。这篇文章解释了一个有用的类型系统分类。

PowerShell是动态、隐式类型的:

> $x=100
> $x=dir

没有类型错误 - 变量可以在运行时更改其类型。这就像PythonPerlJavaScript,但与C++JavaC#等不同。

然而:

> [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那样弱,Perl将根据需要几乎转换任何东西。


3
值得一提的是,像PowerShell这样的动态类型语言通常会出现更差的错误消息和更多的运行时错误,而与之不同的静态类型语言如Java。然而,即使使用静态类型,您仍然可能会遇到空指针异常等运行时错误,只不过您可以获得更好的错误消息和调试体验。 - Kellen Stuart
1
@KolobCanyon 这是因为它是一种脚本语言,在控制台中键入 $obj.SetFlag("None") 并进行隐式转换比 $obj.SetFlag([Company.Example.Product.Data.Transfer.Enums.Flags]::None) 要容易得多。 - marsze

6

如果您需要,它可以是这样的。

就像这样:

[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指出的那样,在执行(5 +“5”)时,这并不能防止PowerShell将“5”解释为整数。我进行了更多的挖掘,并根据Bruce Payette在Windows PowerShell in Action中的说法,PowerShell实际上是一种“类型宽松语言”。因此,我想我的答案是“有点”。

不行。你可以将字符串添加到整数中并获得数字结果。如果你颠倒加法的顺序,你会得到连接。 - Ed Guiness
我认为这表明它可以是静态类型的,这并不意味着它必须是强类型的。 - EBGreen
所以,它是弱类型和静态类型的吗? - John Millikin
1
有点两者皆可,因此称为“淫乱”部分。 :) - David Mohundro

1

PowerShell是一种动态类型的编程语言,简单明了。它被其创造者Bruce Payette描述为这样。

此外,如果有人学过基本的编程语言理论课程,他们就会知道这一点。仅仅因为有类型注释系统并不意味着它是强类型的。即使在转换期间,带有类型注释的变量也会动态地表现出来。任何允许您将字符串分配给变量并打印它,然后将数字分配给同一变量并进行计算的语言都是动态类型的。

此外,PowerShell是动态作用域的(如果这里有人知道这是什么意思)。


1

我认为你需要定义一下“强类型”是什么意思:

在计算机科学和编程中,“强类型”一词用于描述那些编程语言规定了一个或多个限制条件的情况,以控制涉及具有不同数据类型的值的操作如何混合使用。反义词是弱类型。然而,在计算机短暂的历史中,这些术语已经被赋予了各种各样的含义,因此往往很难知道一个作者在使用它们时具体指的是什么。

--维基百科


1

从技术上讲,它是一种强类型语言。

您可以拒绝在 shell 中声明类型,使其表现得像动态类型的脚本语言,但它会将弱类型对象包装在类型为“PsObject”的包装器中。通过使用“New-Object”语法声明对象,对象是强类型的,而不是被包装的。

$compilerParameters = New-Object System.CodeDom.Compiler.CompilerParameters

1

我认为进一步查看将字符串添加到整数的示例会为讨论提供更多素材。什么被认为是动态类型转换?在其中一条评论中,有人说在这种情况下:

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

你可以通过赋值改变变量的类型。如果你执行 $foo="4" 然后 $foo = 8 + $foo,那么 $foo 的类型将从字符串变为整数。但是值是不可变的。 - JacquesB
显然,4 + $foo不会修改变量$foo。这将读取该变量,获取一个字符串,并将其转换为Int32。这是根据$foo的运行时类型(而不是静态类型)动态发生的。 - Jesse

-2

我撤回之前的答案,如下所引用。我应该说得更为微妙:

PowerShell具有强大的类型系统和健壮的类型推断功能,并且是动态类型。

在我看来,这里涉及到几个问题,因此那些要求更好地定义“强类型语言”含义的答案可能更明智地回答了这个问题。

由于PowerShell跨越了许多领域,因此它所处的位置可能存在于以下领域的Venn图中:

  • 静态与动态类型检查
  • 强类型与弱类型
  • 安全类型与不安全类型
  • 显式和隐式声明和推断
  • 结构性和命名类型系统

“PowerShell是一种强类型语言。

但是,它只需要在存在歧义的地方声明类型。

如果可以推断出类型,则不需要指定类型。”


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接