5

次のコードで F と G の戻り値に違いがあるのはなぜですか?

Function F {
    Return (New-Object Collections.Generic.LinkedList[Object])
}

Function G {
    Return New-Object Collections.Generic.LinkedList[Object]
}

Function Write-Type($x) {
    If($null -eq $x) {
        Write-Host "null"
    } Else {
        Write-Host $x.GetType()
    }
}

Write-Type (F) # -> null
Write-Type (G) # -> System.Collections.Generic.LinkedList`1[System.Object]

私が理解している限りでは、関数が何らかの空のコレクションを返す場合、PowerShell はそれを null に "アンラップ" するので、F は私の期待どおりに動作します。しかし、G はどうしたのでしょうか。

編集: JPBlanc が指摘したように、PowerShell 3.0 のみがこの違いを示します。2.0 では、両方の行が出力されますnull。何が変わったのですか?

4

2 に答える 2

3

F は関数を評価するために () を使用しているため、質問を正しく読んでいません。したがって、Write-Type関数の結果は、PowerShell V2.0 でも同じです。

だから、PowerShell 3.0 で私はあなたの問題を満たしています。

現在使用しています:

Trace-Command -name TypeConversion -Expression {Write-Type (F)} -PSHost

Trace-Command -name TypeConversion -Expression {Write-Type (G)} -PSHost

オブジェクトを返す前に () を理解する限り、次を生成します

 Converting "Collections.Generic.LinkedList" to "System.Type".
     Conversion to System.Type
         Conversion to System.Type
             Could not find a match for "System.Collections.Generic.LinkedList".
         Could not find a match for "Collections.Generic.LinkedList".
 Converting "Collections.Generic.LinkedList`1" to "System.Type".
     Conversion to System.Type
         Conversion to System.Type
             Found "System.Collections.Generic.LinkedList`1[T]" in the loaded assemblies.
 Converting "Object" to "System.Type".
     Conversion to System.Type
         Conversion to System.Type
             Found "System.Object" in the loaded assemblies.
于 2013-07-19T10:30:47.267 に答える
0

Powershell 関数に関して言えば、「戻る」とは関数を早期に終了することです。

Bruce P の本 "Powershell in action" の 262 ページを確認したところ、次のように書かれています。

「では、なぜ Powershell は return ステートメントを必要とするのでしょうか? 答えはフロー制御です。関数を早期に終了したい場合があります。return ステートメントがなければ、フロー制御を到達させるために複雑な条件ステートメントを作成する必要があります。終わり..."

また、Keith Hill はこれについて話している非常に良いブログを持っています: http://rkeithhill.wordpress.com/2007/09/16/effective-powershell-item-7-understanding-output/

"......"return $Proc" は、関数の出力のみが $Proc 変数の内容であることを意味するものではありませ。実際、この構造は意味的には "$Proc; 戻る"。 ....."

これに基づいて、関数コードを次のように変更すると、スクリプトの出力は同じになります。

Function F {
    (New-Object Collections.Generic.LinkedList[Object])
    Return 
}

Function G {
   New-Object Collections.Generic.LinkedList[Object]
    Return 
}

この動作は従来の言語とは異なるため、混乱を招きます。

于 2013-07-19T14:01:42.543 に答える