2014-07-03 13 views
8

Có cách nào để xóa các giá trị trả lại bên trong một hàm để tôi có thể đảm bảo rằng giá trị trả lại là những gì tôi định? Hoặc có thể tắt hành vi này cho chức năng?Xóa giá trị đầu ra/trả lại bị xóa trong hàm Powershell

Trong ví dụ này, tôi hy vọng các giá trị trả về là một ArrayList chứa ("Hello", "Thế giới")

function GetArray() 
{ 
    # $AutoOutputCapture = "Off" ? 
    $myArray = New-Object System.Collections.ArrayList 
    $myArray.Add("Hello") 
    $myArray.Add("World") 

    # Clear return value before returning exactly what I want? 
    return $myArray 
} 

$x = GetArray 
$x 

Tuy nhiên, sản lượng có chứa các giá trị thu được từ các hoạt động Add.

0 
1 
Hello 
World 

Tôi thấy tính năng "này" của Powershell rất khó chịu vì nó thực sự dễ dàng phá vỡ chức năng của bạn bằng cách gọi một hàm khác mà bạn không biết trả về giá trị.

Cập nhật

Tôi hiểu có nhiều cách để ngăn chặn đầu ra không bị bắt (như mô tả trong một trong các câu trả lời dưới đây), nhưng điều đó đòi hỏi bạn phải biết rằng một chức năng thực sự trả về một giá trị. Nếu bạn đang gọi một hàm Powershell khác, có thể, trong tương lai, ai đó thay đổi hàm này để trả về một giá trị, sau đó sẽ phá vỡ mã của bạn.

+1

Bạn đã xử lý vấn đề này như thế nào. Đây là tính năng rất khó chịu của PowerShell không cho phép kiểm soát giá trị trả lại. – Feru

+0

Tôi vừa kết thúc bằng cách sử dụng [void] ở khắp mọi nơi. Tôi cũng quyết định làm những việc phức tạp hơn trong C#, sau đó sử dụng PowerShell để dán chúng lại với nhau. – Mas

Trả lời

6

ống đầu ra để Out-Null, chuyển hướng đầu ra để $null, hoặc tiền tố chức năng cuộc gọi với [void]:

$myArray.Add("Hello") | Out-Null 

hoặc

$myArray.Add("Hello") >$null 

hoặc

[void]$myArray.Add("Hello") 
+0

Vâng, tôi biết điều này, nhưng điều đó có nghĩa là tôi phải dẫn đầu ra của mọi lệnh gọi hàm tới null để đảm bảo đầu ra của tôi không bị hỏng, đó là một nỗi đau lớn. Và nếu tôi quên làm điều đó, và mã hoạt động, nó có thể là trong tương lai, người khác thay đổi một chức năng của Powershell và phá vỡ một chức năng khác. – Mas

+1

Có vẻ như câu trả lời là không có giải pháp cho vấn đề này, ngoài việc hủy bỏ mọi cuộc gọi hàm, điều này rất khó chịu. – Mas

0

Tại sao không sử dụng đối tượng Powershell Array, thay vì mảng .Net?

Bạn có thể làm một cái gì đó như:

function GetArray() { 
    # set $myArray as a powershell array 
    $myArray = @() 
    $myArray+="Hello" 
    $myArray+="World" 
    # [email protected]("Hello", "World") would work as well 

    return $myArray 
} 

này sẽ trả về một mảng "sạch", như mong đợi.

Nếu bạn thực sự cần phải có được một System.collections.ArrayList, bạn có thể làm điều đó trong 2 bước sau:

  • tạo ra một mảng PowerShell như đã giải thích ở trên
  • Chuyển đổi mảng powershell của bạn trong một Net ArrayList theo cách này:

    # Get the powershellArray 
    $x = getArray 
    # Create a .Net ArrayList 
    $myArrayList = New-Object System.Collections.ArrayList 
    # Fill your arraylist with the powershell array 
    $myArrayList.AddRange($x) 
    

Hy vọng điều này sẽ giúp một chút.

+2

Mã trong câu hỏi chỉ là một ví dụ về hành vi không mong muốn. Tôi hỏi, nói chung, làm thế nào để xử lý tình trạng này. – Mas

2

Tôi cũng đang có sự thất vọng tương tự này! Tôi có một chức năng mà một biến được cho là để đếm lên $ <variablename> ++

Ngoại trừ. Tôi đã quên "++" ở cuối trong một lần lặp. Mà đã gây ra giá trị của biến được gửi đến bộ đệm đầu ra. Nó rất trầm trọng và tốn nhiều thời gian để tìm! MS nên đã cung cấp, ở mức tối thiểu, một khả năng tuôn ra bộ đệm đầu ra trước khi người dùng được gán giá trị trả lại mong muốn của họ. Bất cứ điều gì ... Tôi tin rằng tôi có một công việc xung quanh.

Vì tôi gán giá trị trả về ở cuối hàm, giá trị mong muốn của tôi sẽ luôn là mục nhập cuối cùng của mảng đệm đầu ra. Vì vậy, tôi đã thay đổi cách tôi gọi chức năng của tôi từ:

If (FunctionName (parameters)) {} 

Để:

If ((FunctionName (parameters))[-1]) {} 

kịch bản đặc biệt của tôi cắn tôi khi tôi đã cố gắng để nắm bắt một hàm $ trở False. vì lỗi đánh máy của tôi ở trên, câu lệnh IF của tôi thấy nó là true vì rác trong đầu ra, mặc dù đầu ra hàm cuối cùng của tôi là "Return $ False". Đầu ra cuối cùng được gán từ hàm này là giá trị $ False do sự cố gây ra lỗi đánh máy. Vì vậy, việc thay đổi Đánh giá chức năng của tôi trở về:

If (!((FunctionName (parameters))[-1])) {#something went wrong!} 

Bí quyết bằng cách cho phép tôi chỉ đánh giá phần tử cuối cùng của mảng đầu ra. Tôi hy vọng điều này sẽ giúp những người khác.

+0

Đây là một mẹo hay nếu bạn mong đợi một giá trị trả về duy nhất. Tôi sẽ ghi nhớ điều này. – Mas

+0

Lưu ý rằng điều này không có tác dụng khi bạn có một giá trị trả về đơn lẻ là một hashtable - bạn sẽ cố gắng lập chỉ mục vào đó. Giải pháp: tiền tố cuộc gọi hàm với 'mảng' như' [mảng] (Hàm tên (tham số)) 'để buộc kết quả là một mảng các giá trị trả về. Điều này sau đó sẽ chứa hashtable của bạn tại chỉ số dự kiến. –

2

Chỉ muốn đăng bài này trong trường hợp có ích. Tôi có nhiều chức năng mà tôi đang gọi. Mỗi hàm trả về 0 hoặc 1. Tôi dùng nó để xem mọi thứ có hoạt động không.

Vì vậy, về cơ bản ...

function Funct1 
{ 
    # Do some things 
    return 1 
} 

$myResult += Funct1 
$myResult += Funct2 
$myResult += Funct3 
if ($myResult -eq 3) { "All is good" } 

Tất cả mọi thứ đã đi cùng tốt cho đến khi tôi đã thêm một chức năng mà đã có một số Copy-Item và lệnh như vậy.

Câu chuyện dài ngắn và một hoặc hai giờ tôi sẽ không bao giờ quay lại, tôi đã phát hiện ra vấn đề tương tự với điều này. Dù sao, với sự giúp đỡ của các trang web như thế này, tôi tìm thấy cách sạch nhất để đảm bảo bạn nhận được "Return" của bạn và không có gì khác.

$myResult += Funct1 -split " " | Select-Object -Last 1 
$myResult += Funct2 -split " " | Select-Object -Last 1 
$myResult += Funct3 -split " " | Select-Object -Last 1 
0

Tôi đã gặp sự cố tương tự. Trong PS, một hàm sẽ trả về tất cả thông tin về đường ống đầu ra. Nó được khéo léo để | Out-Null phần còn lại của mã trong chức năng. Tôi đã làm việc xung quanh điều này bằng cách chuyển biến trả về làm tham số tham chiếu [ref]. Điều này hoạt động nhất quán. Kiểm tra mã mẫu bên dưới. Lưu ý: một số cú pháp rất quan trọng để tránh lỗi. ví dụ. tham số phải được thông qua trong ngoặc ([ref]$result)

function DoSomethingWithFile([ref]$result, [string]$file) 
{ 
    # Other code writing to output 
    # .... 

    # Initialize result 
    if (Test-Path $file){ 
     $result.value = $true 
    } else { 
     $result.value = $false 
    } 
} 
$result = $null 
DoSomethingWithFile ([ref]$result) "C:\test.txt" 
2

Sử dụng thông tin từ user1654962, đây là cách mà tôi đã làm việc xung quanh vấn đề PowerShell này. Vì, nếu có thông tin đầu ra, PowerShell sẽ trả về nó như là một mảng, tôi quyết định đảm bảo đầu ra hàm luôn luôn là một mảng. Sau đó, đường gọi có thể sử dụng [-1] để lấy phần tử cuối cùng của mảng và chúng ta sẽ nhận được một giá trị trả về nhất quán.

function DoSomething() 
{ 
    # Code that could create output 
    Write-Output "Random output that we don't need to return" 
    Write-Output "More random output" 

    # Create the return value. It can be a string, object, etc. 
    $MyReturnString = "ImportantValue" 

    # Other code 

    # Make sure the return value is an array by preceding it with a comma 
    return ,$MyReturnString 
} 

$CleanReturnValue = (DoSomething())[-1] 
Các vấn đề liên quan