我在安装了Powershell7.1的Win10 Pro计算机上遇到了以下问题:以下是脚本:
function hoursInSeconds ([String] $hour){
# $hour expected format: hh:mm:ss
$par = $hour.Split(":")
$secs = [int]$par[0] * 3600 + [int]$par[1] * 60 + [int]$par[2]
return $secs
}
$a = "17:55:11"
$b = "18:06:00"
$c = hoursInSeconds($b) - hoursInSeconds($a)
Write-Host "c:" $c
$aSec = hoursInSeconds($a)
$bSec = hoursInSeconds($b)
$d = $bSec - $aSec
$bSec.GetType().FullName
hoursInSeconds($a).GetType().FullName
Write-Host "a, b, aSec, bSec, d:" $a $b $aSec $bSec $d
因为函数调用的构造并没有像我预期的那样工作
我原以为(64511-65160=649,结果是“c:65160”),
通过查看函数调用的格式,我试图找出原因:
hoursInSeconds($a).GetType().FullName
但后来我收到了另一个错误。
以下是全部输出:
c: 65160
System.Int32
a, b, aSec, bSec, d: 17:55:11 18:06:00 64511 65160 649
Cannot convert value "System.String" to type "System.Int32". Error: "Input string was not in a correct format."
At D:\DEVELOP\Powershell\TimeFunctions_1.ps1:4 char:5
+ $secs = [int]$par[0] * 3600 + [int]$par[1] * 60 + [int]$par[2]
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvalidCastFromStringToInteger
因此,这里有两个问题,可能是相互依赖的:
1.为什么不这样做呢?和
1.为什么.GetType().FullName不是这样工作的?
有什么想法吗?
谢谢
1条答案
按热度按时间w6lpcovy1#
您有一个语法问题:
注:此上下文中的错误意味着:语法在形式上是有效的,但并没有如您所期望的那样。
它应该是:
请注意更正:
(...)
中。-
、减法运算符,或方法调用和/或属性访问-例如.GetType()
和.FullName
-**它们必须包含在(...)
**分组运算符中-有关详细信息,请参阅this answer。要传递给函数的参数现在与函数名之间用空格分隔;类似地,必须使用空格(而不是
,
)来分隔多个参数。简而言之:PowerShell命令(函数、cmdlet、脚本和外部程序)必须像外壳命令-
foo arg1 arg2
-而不是像C#方法那样被调用-foo('arg1', 'arg2')
。**如果使用
,
而不是空格来分隔参数,则会构造一个数组,命令会将其视为单个参数。为了防止意外使用方法语法,您可以使用
Set-StrictMode -Version 2
或更高版本,但请注意它的其他影响。有关详细信息,请参阅this answer。至于您的命令是如何解释的:
hoursInSeconds($b) - hoursInSeconds($a)
调用意外地被解析为hoursInSeconds
的单个调用,其值为$b
,逐字地为-
和hoursInSeconds
,最后将$a
的值all作为参数传递给该单个调用-由于您的函数不强制传递什么(额外的)参数,因此它们不会被注意到,因此实际上只执行了hoursInSeconds $b
。hoursInSeconds($a).GetType().FullName
调用的解析如下:($a).GetType().FullName
先计算*,因为$a
是字符串,所以结果是逐字字符串System.String
,然后将其作为参数传递给函数hoursInSeconds
-这会失败,因为参数不是预期的"HH:mm:ss"
字符串格式。另外,您可以简化您的函数,使用
[timespan]
(System.TimeSpan
)类:请注意,在这个简单的例子中,
return
不是必需的;在PowerShell中,您只需要return
来执行控制流,而不是数据输出。任何命令或表达式的输出既没有被捕获、重定向,也没有通过管道发送到另一个命令,就是隐式输出-有关更多信息,请参阅this answer的底部部分。