Saya telah mengembangkan fungsi PowerShell yang melakukan sejumlah tindakan yang melibatkan penyediaan situs Tim SharePoint . Pada akhirnya, saya ingin fungsi untuk mengembalikan URL situs yang disediakan sebagai String sehingga pada akhir fungsi saya, saya memiliki kode berikut:
$rs = $url.ToString();
return $rs;
Kode yang memanggil fungsi ini terlihat seperti:
$returnURL = MyFunction -param 1 ...
Jadi saya mengharapkan String, namun tidak. Sebaliknya, ini adalah objek bertipe System.Management.Automation.PSMethod. Mengapa mengembalikan tipe itu dan bukan tipe String?
powershell
ChiliYago
sumber
sumber
Jawaban:
PowerShell benar-benar mengembalikan semantik - setidaknya jika dilihat dari perspektif pemrograman yang lebih tradisional. Ada dua ide utama untuk membungkus kepala Anda:
Dengan demikian, dua blok skrip berikut akan melakukan hal yang sama persis secara efektif:
Variabel $ a dalam contoh kedua dibiarkan sebagai output pada pipeline dan, sebagaimana disebutkan, semua output dikembalikan. Bahkan, dalam contoh kedua Anda bisa menghilangkan pengembalian sepenuhnya dan Anda akan mendapatkan perilaku yang sama (pengembalian akan tersirat sebagai fungsi secara alami melengkapi dan keluar).
Tanpa lebih banyak definisi fungsi Anda, saya tidak bisa mengatakan mengapa Anda mendapatkan objek PSMethod. Dugaan saya adalah bahwa Anda mungkin memiliki sesuatu beberapa baris di atas yang tidak ditangkap dan ditempatkan pada pipa keluaran.
Perlu juga dicatat bahwa Anda mungkin tidak membutuhkan titik koma itu - kecuali jika Anda bersarang banyak ekspresi pada satu baris.
Anda dapat membaca lebih lanjut tentang semantik kembali di halaman about_Return di TechNet, atau dengan menjalankan
help return
perintah dari PowerShell itu sendiri.sumber
write-debug
setelah mengatur variabel$DebugPreference = "Continue"
sebagai gantinya"SilentlyContinue"
echo
adalah masalah bagi saya! Titik kecil itu sangat penting. Saya mengembalikan hashtable, mengikuti yang lainnya, tapi tetap saja nilai pengembaliannya tidak seperti yang saya harapkan. Dihapusecho
dan bekerja seperti pesona.Bagian dari PowerShell ini mungkin merupakan aspek yang paling bodoh. Output luar yang dihasilkan selama suatu fungsi akan mencemari hasilnya. Terkadang tidak ada output, dan kemudian dalam beberapa kondisi ada beberapa output yang tidak terencana, selain nilai pengembalian yang Anda rencanakan.
Jadi, saya menghapus tugas dari panggilan fungsi asli, sehingga output berakhir di layar, dan kemudian melangkah sampai sesuatu yang saya tidak rencanakan untuk muncul di jendela debugger (menggunakan PowerShell ISE ).
Bahkan hal-hal seperti pemesanan variabel dalam lingkup luar menyebabkan output, seperti
[boolean]$isEnabled
yang akan memuntahkan False keluar kecuali Anda membuatnya[boolean]$isEnabled = $false
.Satu lagi yang bagus adalah
$someCollection.Add("thing")
yang mengeluarkan jumlah koleksi baru.sumber
[boolean]$a
di PowerShell tidak benar-benar mendeklarasikan variabel $ a. Anda dapat mengkonfirmasi ini dengan mengikuti baris itu dengan baris$a.gettype()
dan membandingkan output itu ketika Anda mendeklarasikan dan menginisialisasi dengan string$a = [boolean]$false
.>
dan<
sudah digunakan untuk pengalihan aliran I / O ke / dari file.>=
menulis stdout ke file bernama=
.Dengan PowerShell 5 kami sekarang memiliki kemampuan untuk membuat kelas. Ubah fungsi Anda menjadi kelas, dan kembali hanya akan mengembalikan objek segera sebelum itu. Ini adalah contoh sederhana yang nyata.
Jika ini adalah fungsi, output yang diharapkan adalah
tetapi sebagai kelas satu-satunya hal yang dikembalikan adalah bilangan bulat 808979. Kelas semacam jaminan bahwa itu hanya akan mengembalikan tipe yang dinyatakan atau tidak berlaku.
sumber
static
metode. Menuju sintaksis[test_class]::return_what()
return 808979
, berfungsi atau tidak.Write-Output
? Ini bukan output "konsol" yang dimaksud di sini, ini adalah output untuk fungsi / cmdlet. Jika Anda ingin membuang barang di konsol adaWrite-Verbose
,Write-Host
danWrite-Error
fungsi, antara lain. Pada dasarnya,Write-Output
lebih dekat kereturn
semantik, daripada ke prosedur keluaran konsol. Jangan menyalahgunakannya, gunakanWrite-Verbose
untuk kata kerja, itulah gunanya .Sebagai solusinya saya telah mengembalikan objek terakhir dalam array yang Anda dapatkan kembali dari fungsi ... Ini bukan solusi yang bagus, tetapi lebih baik daripada tidak sama sekali:
Secara keseluruhan, cara menulis yang sama secara garis lurus adalah:
sumber
$b = $b[-1]
akan menjadi cara yang lebih sederhana untuk mendapatkan elemen terakhir atau array, tetapi lebih sederhana lagi adalah dengan tidak menampilkan nilai yang tidak Anda inginkan.write-host
untuk output secara langsung.Saya melewati objek Hashtable sederhana dengan anggota hasil tunggal untuk menghindari kegilaan kembali karena saya juga ingin menampilkan ke konsol. Bertindak melalui referensi dengan referensi.
Anda dapat melihat contoh penggunaan nyata di proyek GitHub saya unpackTunes .
sumber
Sulit untuk mengatakan tanpa melihat kode. Pastikan fungsi Anda tidak mengembalikan lebih dari satu objek dan Anda menangkap setiap hasil yang dibuat dari panggilan lain. Apa yang Anda dapatkan untuk:
Pokoknya, dua saran:
Keluarkan objek ke string:
Atau cukup lampirkan dalam tanda kutip ganda, sama seperti di atas tetapi lebih pendek untuk mengetik:
sumber
"$rs"
-return
hanya diperlukan ketika kembali lebih awal dari fungsi. Meninggalkan pengembalian adalah idiom PowerShell yang lebih baik.Deskripsi fungsi hasil Luke skenario ini tampaknya benar. Saya hanya ingin memahami akar permasalahan dan tim produk PowerShell akan melakukan sesuatu tentang perilaku tersebut. Tampaknya cukup umum dan telah menghabiskan banyak waktu debugging.
Untuk mengatasi masalah ini saya telah menggunakan variabel global daripada mengembalikan dan menggunakan nilai dari pemanggilan fungsi.
Inilah pertanyaan lain tentang penggunaan variabel global: Mengatur variabel PowerShell global dari fungsi di mana nama variabel global adalah variabel yang diteruskan ke fungsi
sumber
Berikut ini hanya mengembalikan 4 sebagai jawaban. Ketika Anda mengganti ekspresi tambah untuk string itu mengembalikan string pertama.
Ini juga bisa dilakukan untuk array. Contoh di bawah ini akan mengembalikan "Teks 2"
Perhatikan bahwa Anda harus memanggil fungsi di bawah fungsi itu sendiri. Kalau tidak, saat pertama kali dijalankan, ia akan mengembalikan kesalahan yang tidak tahu apa itu "StartingMain".
sumber
Jawaban yang ada sudah benar, tetapi kadang-kadang Anda tidak benar-benar mengembalikan sesuatu secara eksplisit dengan a
Write-Output
atau areturn
, namun ada beberapa nilai misteri dalam hasil fungsi. Ini bisa menjadi output dari fungsi builtin likeNew-Item
Semua kebisingan tambahan dari pembuatan direktori sedang dikumpulkan dan dipancarkan dalam output. Cara mudah untuk mengurangi ini adalah dengan menambahkan
| Out-Null
ke akhirNew-Item
pernyataan, atau Anda dapat menetapkan hasilnya ke variabel dan tidak menggunakan variabel itu. Akan terlihat seperti ini ...New-Item
mungkin yang lebih terkenal dari ini, tetapi yang lain termasuk semuaStringBuilder.Append*()
metode, sertaSqlDataAdapter.Fill()
metode.sumber