PowerShell类方法的引用参数?[参考资料][Uint64]
我有一个powershell类,需要传入对UInt64变量的引用,并从该方法返回一个值。我试图在下面的代码中执行类似的操作,但它给了我一个语法错误 也许我不需要添加?[ref]?因为默认情况下,所有变量都是powershell中的引用,包括uint64?但我只是不确定这是不是真的。。。。如果我遵循正常的C语言约定,那么该方法将获得参数的副本,而不是变量的实际引用。我似乎还记得C语言中关于装箱和拆箱int类型的一些东西。。。Powershell类方法的装箱Int是如何工作的PowerShell类方法的引用参数?[参考资料][Uint64],powershell,Powershell,我有一个powershell类,需要传入对UInt64变量的引用,并从该方法返回一个值。我试图在下面的代码中执行类似的操作,但它给了我一个语法错误 也许我不需要添加?[ref]?因为默认情况下,所有变量都是powershell中的引用,包括uint64?但我只是不确定这是不是真的。。。。如果我遵循正常的C语言约定,那么该方法将获得参数的副本,而不是变量的实际引用。我似乎还记得C语言中关于装箱和拆箱int类型的一些东西。。。Powershell类方法的装箱Int是如何工作的 class Powe
class PowerHe11 {
# Constructor
PowerHe11() {
}
[void]AccessChannel(
[UInt64]$ichan,
[UInt64]$idata,
[UInt64]$isize,
[UInt64]$ireal,
[ref][UInt64]$otimeout,
[ref][UInt64]$odata,
[ref][UInt64]$ochan,
[ref][UInt64]$osize
) {
$osize = 64; #Return this value to caller of method
}
}
错误消息是:
At C:\Users\wmoore\Documents\fpga\zynq_pl\run_ps1\Untitled1.ps1:13 char:11
+ [ref][UInt64]$otimeout,
+ ~~~~~~~~
Multiple type constraints are not allowed on a method parameter.
At C:\Users\wmoore\Documents\fpga\zynq_pl\run_ps1\Untitled1.ps1:14 char:14
+ [ref][UInt64]$odata,
+ ~~~~~~~~
Multiple type constraints are not allowed on a method parameter.
At C:\Users\wmoore\Documents\fpga\zynq_pl\run_ps1\Untitled1.ps1:15 char:14
+ [ref][UInt64]$ochan,
+ ~~~~~~~~
Multiple type constraints are not allowed on a method parameter.
At C:\Users\wmoore\Documents\fpga\zynq_pl\run_ps1\Untitled1.ps1:16 char:14
+ [ref][UInt64]$osize
+ ~~~~~~~~
Multiple type constraints are not allowed on a method parameter.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : MultipleTypeConstraintsOnMethodParam
给出了解决方案;让我添加一个解释和背景信息:
是官方的帮助主题
简而言之:
[ref]的主要目的是支持.NET方法中的ref和out参数;e、 例如,要调用该方法,请使用以下命令:
[int]$int=0;[int]::TryParse'42',[ref]$int
请注意,变量的类型必须与.NET方法所期望的类型匹配,并且在PowerShell中创建变量的唯一方法是也为其分配一个值,即使该值不相关,就像手头的out参数一样;[ref]转换的要求类似于在C中使用ref或out的需要
如果您对该方法分配的值不感兴趣,则可以传递[ref]$null
虽然您可以在PowerShell代码中使用它,但这样做很尴尬,如您的示例所示:
如您的答案所示,接收[ref]参数的PowerShell代码必须通过.value属性引用其值
不能对此类参数进行类型约束,因此将失去类型安全性
请注意,在函数和脚本中(与自定义类方法相反),语法上允许同时使用[ref]和目标数据类型(如[ref][UInt64]$otimeout),但在示例中没有意义,因为后者实际上被忽略;e、 g:
函数foo{param[ref][int]$p$p.Value+='!'}$bar=‘无’;foo[ref]$bar$酒吧
调用成功,$bar包含'none!',这意味着[int]类型约束被忽略
调用脚本和函数需要类似shell的、空格分隔的参数和允许的裸字字符串,这使得[ref]-cast调用需要。。。围绕参数,如上所示foo[ref]$bar
关于在自定义PuxBar类中使用,请注意,按设计,不等同于面向对象的语言(如C);也就是说,正在计划改进;不幸的是,从PowerShell 7.1开始,即使是有限的功能集也存在问题-请参阅
[ref]的技术背景: [ref]与C中的ref不同,它不是一个语言关键字:它是一个类型,即它的is[ref] 因此,像[ref]$var这样的表达式是隐式构造[ref]实例的强制转换,绑定到[ref]类型的参数需要该实例 注意事项: [ref]强制转换涉及到解析器魔法,因为您不能直接使用通常等价的[ref]::新的$var构造函数表达式作为强制转换[ref]$var的替代。 PowerShell需要magic知道$var引用的是变量对象本身,而不是变量的值,这在表达式中通常是这样的-后者确实与[ref]有关::新的$var-$var的值包装在[ref]实例中。 与[ref]$var等效的真正构造函数是[ref]::newGet变量var 断开:不要使用构造函数-[ref]::新建$int- 代替演员阵容-[ref]$int PS>[int]$int=0$null=[int]::TryParse'42',[ref]::new$int$int 0 !! $int没有更新,因为它的*value*被包装在[ref]实例中 通常,只有将[ref]强制转换与可变对象操作数一起使用才有意义 PowerShell允许您将任何值作为操作数传递,这在技术上是可行的,但没有意义,除非您将[ref]实例显式保存在变量中,将其作为参数传递,然后使用[ref]实例的.value属性访问更新后的值: 将[ref]实例保存在变量中,传递它,然后使用.Value获取 更新值。 PS>[ref]$intRef=0$null=[int]::TryParse'42',$intRef$intRef.值 42 给出了解决方案;让我添加一个解释和背景信息: 是官方的帮助主题 简而言之: [ref]的主要目的是支持.NET方法中的ref和out参数;e、 例如,要调用该方法,请使用以下命令: [int]$int=0;[int]::TryParse'42',[ref]$int 请注意,变量的类型必须与.NET方法所期望的类型匹配,并且在PowerShell中创建变量的唯一方法是也为其分配一个值,即使该值不相关,就像手头的out参数一样;[ref]转换的要求类似于在C中使用ref或out的需要 你可以通过[ref] $null,如果您对该方法分配的值不感兴趣 虽然您可以在PowerShell代码中使用它,但这样做很尴尬,如您的示例所示: 如您的答案所示,接收[ref]参数的PowerShell代码必须通过.value属性引用其值 不能对此类参数进行类型约束,因此将失去类型安全性 请注意,在函数和脚本中(与自定义类方法相反),语法上允许同时使用[ref]和目标数据类型(如[ref][UInt64]$otimeout),但在示例中没有意义,因为后者实际上被忽略;e、 g: 函数foo{param[ref][int]$p$p.Value+='!'}$bar=‘无’;foo[ref]$bar$酒吧 调用成功,$bar包含'none!',这意味着[int]类型约束被忽略 调用脚本和函数需要类似shell的、空格分隔的参数和允许的裸字字符串,这使得[ref]-cast调用需要。。。围绕参数,如上所示foo[ref]$bar关于在自定义PuxBar类中使用,请注意,按设计,不等同于面向对象的语言(如C);也就是说,正在计划改进;不幸的是,从PowerShell 7.1开始,即使是有限的功能集也存在问题-请参阅
[ref]的技术背景: [ref]与C中的ref不同,它不是一个语言关键字:它是一个类型,即它的is[ref] 因此,像[ref]$var这样的表达式是隐式构造[ref]实例的强制转换,绑定到[ref]类型的参数需要该实例 注意事项: [ref]强制转换涉及到解析器魔法,因为您不能直接使用通常等价的[ref]::新的$var构造函数表达式作为强制转换[ref]$var的替代。 PowerShell需要magic知道$var引用的是变量对象本身,而不是变量的值,这在表达式中通常是这样的-后者确实与[ref]有关::新的$var-$var的值包装在[ref]实例中。 与[ref]$var等效的真正构造函数是[ref]::newGet变量var 断开:不要使用构造函数-[ref]::新建$int- 代替演员阵容-[ref]$int PS>[int]$int=0$null=[int]::TryParse'42',[ref]::new$int$int 0 !! $int没有更新,因为它的*value*被包装在[ref]实例中 通常,只有将[ref]强制转换与可变对象操作数一起使用才有意义 PowerShell允许您将任何值作为操作数传递,这在技术上是可行的,但没有意义,除非您将[ref]实例显式保存在变量中,将其作为参数传递,然后使用[ref]实例的.value属性访问更新后的值: 将[ref]实例保存在变量中,传递它,然后使用.Value获取 更新值。 PS>[ref]$intRef=0$null=[int]::TryParse'42',$intRef$intRef.值 42class powerhe11 {
# Constructor
powerhe11() {
}
[void]AccessChannel(
[ref]$ichan
) {
$ichan.value = 0xbeef;
Write-Host("ichan: {0}" -f $ichan.value)
}
}
[UInt64]$dude = 0
$ser = [gvmuart]::new()
$ser.AccessChannel([ref]$dude);
Write-Host -BackgroundColor Green "DUDE: $dude"