Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Deskripsi singkat
PowerShell memiliki sistem jenis fleksibel yang membuatnya lebih mudah digunakan. Namun, Anda harus memahami cara kerjanya untuk menghindari hasil yang tidak terduga.
Deskripsi panjang
Secara default, variabel PowerShell tidak yang dibatasi jenis. Anda dapat membuat variabel yang berisi instans dari satu jenis dan kemudian menetapkan nilai dari jenis lain. Selain itu, PowerShell secara otomatis mengonversi nilai ke jenis lain, baik secara eksplisit maupun implisit. Meskipun konversi jenis implisit dapat membantu, ada jebakan, terutama untuk pengguna yang lebih akrab dengan bahasa yang memiliki penanganan jenis yang lebih ketat.
Variabel yang dibatasi jenis dan konversi jenis eksplisit
Untuk membatasi jenis variabel, tempatkan jenis harfiah di sebelah kiri nama variabel dalam penugasan. Misalnya:
[int]$foo = 42
Anda dapat menggunakan pengecoran jenis untuk mengonversi nilai secara eksplisit ke jenis tertentu. Misalnya:
PS> $var = [int]'43'
PS> $var.GetType().Name
Int32
Pembatasan jenis memastikan bahwa hanya nilai dari jenis yang ditentukan yang dapat ditetapkan ke variabel. PowerShell melakukan konversi implisit jika Anda mencoba menetapkan nilai dari jenis berbeda yang dapat dikonversi ke jenis yang dibatasi. Untuk informasi selengkapnya, lihat bagian konversi jenis implisit di artikel ini.
Konversi jenis numerik
Jenis numerik dapat dikonversi ke jenis numerik lainnya selama jenis target mampu menahan nilai yang dikonversi. Misalnya:
PS> (42.1).GetType().Name
Double
PS> $byte = [byte] 42.1
PS> $byte
42
PS> $byte.GetType().Name
Byte
Nilai 42.1 adalah Ganda. Ketika Anda melemparkannya ke Byte, PowerShell memotongnya ke bilangan bulat 42, yang cukup kecil untuk dimasukkan ke dalam byte .
Saat mengonversi angka riil ke jenis bilangan bulat, PowerShell menggunakan pembulatan daripada pemotongan, khususnya menggunakan metode pembulatan-ke-terdekat bahkan.
Contoh berikut mengilustrasikan perilaku ini. Kedua nilai dibulatkan ke bilangan bulat genap terdekat, 22.
PS> [byte]21.5
22
PS> [byte]22.5
22
Untuk informasi selengkapnya, lihat bagian nilai titik tengah dan konvensi pembulatan dari metode Math.Round.
Konversi jenis Boolean
Nilai jenis apa pun dapat dipaksa ke Boolean.
Untuk jenis numerik,
0dikonversi ke$falsedan nilai lainnya dikonversi ke$true.PS> [boolean]0 False PS> [boolean]0.0 False PS> [boolean]-1 True PS> [boolean]1 True PS> [boolean]42.1 TrueUntuk jenis lain, nilai null, string kosong, dan array kosong dikonversi ke
$false.PS> [boolean]'' False PS> [boolean]@() False PS> [boolean]'Hello' TrueNilai lain, termasuk hashtable kosong dikonversi ke
$true. Koleksi elemen tunggal mengevaluasi ke nilai Boolean dari satu dan satu-satunya elemennya. Koleksi dengan lebih dari 1 elemen selalu$true.PS> [boolean]@(0) False PS> [boolean]@(0,0) True PS> [boolean]@{} True
Konversi jenis string
Nilai jenis apa pun dapat dipaksa ke String . Konversi default adalah memanggil metode ToString() pada objek.
Array dikonversi menjadi string. Setiap elemen dalam array dikonversi menjadi string, satu per satu dan digabungkan ke string yang dihasilkan. Secara default, nilai yang dikonversi dipisahkan oleh spasi. Pemisah dapat diubah dengan mengatur variabel preferensi $OFS.
PS> [string] @(1, 2, 3)
1 2 3
Untuk informasi selengkapnya tentang $OFS, lihat about_Preference_Variables.
Nilai string tunggal dapat dikonversi ke instans jenis jika jenis mengimplementasikan metode Parse() statis. Misalnya, [bigint]'42' sama dengan [bigint]::Parse('42', [cultureinfo]::InvariantCulture). Nilai [cultureinfo]::InvariantCulture opsional mengikat parameter jenis IFormatProvider metode. Ini memastikan perilaku konversi yang invarian budaya. Tidak semua implementasi metode Parse() memiliki parameter ini.
Nota
Konversi ke dan dari string biasanya dilakukan menggunakan budaya invarian. Budaya invarian didasarkan pada, tetapi tidak identik dengan, budaya US-English. Terutama, ia menggunakan periode (.) sebagai tanda desimal dan tanggal pertama bulan gaya AS secara default. Namun, cmdlet biner melakukan konversi sensitif budaya selama pengikatan parameter.
Konversi jenis enum
PowerShell dapat mengonversi jenis Enum ke dan dari instans String. Misalnya, string typecast [System.PlatformId]'Unix' sama dengan nilai enum [System.PlatformId]::Unix. PowerShell juga menangani enum berbasis bendera dengan benar untuk nilai yang dipisahkan koma di dalam string atau sebagai array string. Pertimbangkan contoh berikut:
[System.Reflection.TypeAttributes]'Public, Abstract'
[System.Reflection.TypeAttributes]('Public', 'Abstract')
Contoh-contoh ini setara dengan ekspresi enum:
[System.Reflection.TypeAttributes]::Public -bor
[System.Reflection.TypeAttributes]::Abstract
Konversi jenis lainnya
Nilai tunggal (non-array) dapat dikonversi ke instans jenis jika:
- Jenis tersebut memiliki konstruktor parameter tunggal (publik)
- Dan nilainya adalah jenis yang sama atau dapat dipaksa ke jenis parameter
Misalnya, dua baris berikut setara:
[regex]'a|b'
[regex]::new('a|b')`
Jenis implisit
PowerShell juga menetapkan jenis ke nilai harfiah secara otomatis.
Literal numerik secara implisit ditik secara default. Angka ditik berdasarkan ukurannya. Misalnya, 42 cukup kecil untuk disimpan sebagai jenis Int32 dan 1.2 disimpan sebagai Double. Bilangan bulat yang lebih besar dari [int32]::MaxValue disimpan sebagai Int64. Meskipun 42 dapat disimpan sebagai Byte dan 1.2 dapat disimpan sebagai jenis Tunggal, pengetikan implisit menggunakan Int32 dan Double masing-masing. Untuk informasi selengkapnya, lihat about_Numeric_Literals.
String literal secara implisit dititikkan sebagai string . Instans String karakter tunggal dapat dikonversi ke dan dari jenis karakter. Namun, PowerShell tidak memiliki jenis Char harfiah.
Konversi jenis implisit
Dalam konteks tertentu, PowerShell dapat secara implisit mengonversi nilai ke jenis lain. Konteks ini meliputi:
- Pengikatan parameter
- Variabel yang dibatasi jenis
- Ekspresi menggunakan operator
- Konteks Boolean - PowerShell mengonversi ekspresi kondisional pernyataan
if,while,do, atauswitchmenjadi nilai Boolean, seperti yang dijelaskan sebelumnya. Untuk informasi selengkapnya, lihat about_Booleans. - Definisi jenis Extended Type System (ETS) - Konversi jenis dapat ditentukan dalam beberapa cara:
- Menggunakan parameter TypeConverterUpdate-TypeData
- Dalam file type.ps1xml
- Dalam kode yang dikompilasi untuk jenis yang dihiasi dengan atribut TypeConverterAttribute
- Melalui kelas yang berasal dari TypeConverter atau PSTypeConverter
Konversi pengikatan parameter
PowerShell mencoba mengonversi nilai yang diteruskan ke parameter agar sesuai dengan jenis parameter. Konversi jenis nilai parameter terjadi dalam cmdlet, fungsi, skrip, blok skrip, atau metode .NET tempat parameter dideklarasikan dengan jenis tertentu. Mendeklarasikan parameter dengan jenis [Object] atau tidak menentukan jenis tertentu memungkinkan jenis nilai apa pun diteruskan ke parameter. Parameter juga dapat memiliki konversi kustom yang ditentukan dengan mendekorasi parameter dengan atribut ArgumentTransformationAttribute.
Untuk informasi selengkapnya, lihat about_Parameter_Binding.
Praktik terbaik untuk pengikatan parameter
Untuk metode .NET, lebih baik melewati jenis yang tepat yang diharapkan menggunakan jenis cast jika diperlukan. Tanpa jenis yang tepat, PowerShell dapat memilih metode yang salah kelebihan beban. Selain itu, kelebihan beban metode baru yang ditambahkan dalam versi .NET yang akan datang dapat merusak kode yang ada. Untuk contoh ekstrem dari masalah ini, lihat pertanyaan Stack Overflow ini.
Jika Anda meneruskan array ke parameter [string] yang ditik, PowerShell mungkin mengonversi array menjadi string seperti yang dijelaskan sebelumnya. Pertimbangkan fungsi dasar berikut:
function Test-String {
param([string] $String)
$String
}
Test-String -String 1, 2
Fungsi ini menghasilkan 1 2 karena array dikonversi menjadi string. Untuk menghindari perilaku ini, buat fungsi tingkat lanjut dengan menambahkan atribut [CmdletBinding()].
function Test-String {
[CmdletBinding()]
param([string] $String)
$String
}
Test-String -String 1, 2
Untuk fungsi tingkat lanjut, PowerShell menolak untuk mengikat array ke jenis non-array. Saat Anda meneruskan array, PowerShell mengembalikan pesan kesalahan berikut:
Test-String:
Line |
7 | Test-String -String 1, 2
| ~~~~
| Cannot process argument transformation on parameter 'String'. Cannot
| convert value to type System.String.
Sayangnya, Anda tidak dapat menghindari perilaku ini untuk panggilan metode .NET.
PS> (Get-Date).ToString(@(1, 2))
1 2
PowerShell mengonversi array ke string "1 2", yang diteruskan ke parameter Format dari metode ToString().
Contoh berikut menunjukkan instans lain dari masalah konversi array.
PS> $bytes = [byte[]] @(1..16)
PS> $guid = New-Object System.Guid($bytes)
New-Object: Cannot find an overload for "Guid" and the argument count: "16".
PowerShell memperlakukan array $bytes sebagai daftar parameter individual meskipun $bytes adalah array byte dan System.Guid memiliki konstruktor Guid(byte[]).
Pola kode umum ini adalah instans sintaks metode pseudo , yang tidak selalu berfungsi seperti yang dimaksudkan. Sintaks ini diterjemahkan ke:
PS> [byte[]] $bytes = 1..16
PS> New-Object -TypeName System.Guid -ArgumentList $bytes
New-Object: Cannot find an overload for "Guid" and the argument count: "16".
Mengingat bahwa jenis ArgumentList [Object[]], argumen tunggal yang kebetulan merupakan array (dari jenis apa pun) mengikatnya elemen berdasarkan elemen. Solusinya adalah membungkus $bytes dalam array luar sehingga PowerShell mencari konstruktor dengan parameter yang cocok dengan konten array luar.
PS> [byte[]] $bytes = 1..16
PS> $guid = New-Object -TypeName System.Guid -ArgumentList (, $bytes)
PS> $guid
Guid
----
04030201-0605-0807-090a-0b0c0d0e0f10
Item pertama dari array yang dibungkus adalah instans [byte[]] asli kami. Nilai tersebut cocok dengan konstruktor Guid(byte[]).
Alternatif untuk solusi pembungkusan array adalah dengan menggunakan metode new() statis intrinsik.
PS> [byte[]] $bytes = 1..16
PS> [System.Guid]::new($bytes) # OK
Guid
----
04030201-0605-0807-090a-0b0c0d0e0f10
Konversi variabel yang dibatasi jenis
Saat Anda menetapkan nilai ke variabel yang dibatasi jenis, PowerShell mencoba mengonversi nilai ke jenis variabel. Jika nilai yang disediakan dapat dikonversi ke jenis variabel, penugasan berhasil.
Misalnya:
PS> [int]$foo = '43'
PS> $foo.GetType().Name
Int32
Konversi berfungsi karena string '43' dapat dikonversi menjadi angka.
Konversi operator
PowerShell dapat secara implisit mengonversi operand dalam ekspresi untuk menghasilkan hasil yang wajar. Selain itu, beberapa operator memiliki perilaku khusus jenis.
Operasi numerik
Dalam operasi numerik, bahkan jika kedua operand adalah jenis numerik yang sama, hasilnya bisa menjadi jenis yang berbeda, karena konversi jenis otomatis untuk mengakomodasi hasilnya.
PS> [int]$a = 1
PS> [int]$b = 2
PS> $result = $a / $b
PS> $result
0.5
PS> $result.GetType().Name
Double
Meskipun kedua operand adalah bilangan bulat, hasilnya dikonversi ke Double untuk mendukung hasil pecahan. Untuk mendapatkan pembagian bilangan bulat sejati, gunakan metode statis [int]::Truncate() atau [Math]::DivRem(). Untuk informasi selengkapnya, lihat Truncate() dan DivRem().
Dalam aritmatika bilangan bulat, ketika hasil meluapkan ukuran operand, PowerShell default menggunakan Double untuk hasilnya, bahkan ketika hasilnya dapat masuk ke dalam jenis Int64.
PS> $result = [int]::MaxValue + 1
PS> $result
2147483648
PS> $result.GetType().Name
Double
Jika Anda ingin hasilnya menjadi Int64, Anda dapat melemparkan jenis hasil atau operand.
PS> ([int64]([int]::MaxValue + 1)).GetType().Name
Int64
Namun, gunakan perawatan saat melemparkan hasil ke jenis tertentu. Misalnya, pengecoran jenis hasil ke jenis [decimal] dapat menyebabkan hilangnya presisi.
Menambahkan 1 ke nilai maksimum Int64 menghasilkan jenis Ganda. Saat Anda melemparkan Double ke jenis Desimal, hasilnya 9223372036854780000, yang tidak akurat.
PS> ([int64]::MaxValue + 1).GetType().Name
Double
PS> [decimal]([int64]::MaxValue + 1)
9223372036854780000
Konversi dibatasi hingga 15 digit presisi. Untuk informasi selengkapnya, lihat bagian Keterangan dari dokumentasi konstruktor Desimal (Ganda).
Untuk menghindari hilangnya presisi, gunakan akhiran D pada 1 harfiah. Dengan menambahkan akhiran D, PowerShell mengonversi [int64]::MaxValue ke Desimal sebelum menambahkan 1D.
PS> ([int64]::MaxValue + 1D).GetType().Name
Decimal
PS> ([int64]::MaxValue + 1D)
9223372036854775808
Untuk informasi selengkapnya tentang akhiran numerik, lihat about_Numeric_Literals.
Biasanya, operan sisi kiri (LHS) operator PowerShell menentukan jenis data yang digunakan dalam operasi. PowerShell mengonversi (koerce) operand sisi kanan (RHS) ke jenis yang diperlukan.
PS> 10 - ' 9 '
1
Dalam contoh ini, operand RHS adalah string ' 9 ', yang secara implisit dikonversi menjadi bilangan bulat sebelum operasi pengurangan. Hal yang sama berlaku untuk operator perbandingan.
PS> 10 -eq ' 10'
True
PS> 10 -eq '0xa'
True
Ada pengecualian saat menggunakan operator arithmetic_ (+, -, *, /) dengan operan non-numerik.
Saat Anda menggunakan - dan / operand dengan string, PowerShell mengonversi kedua operan dari string menjadi angka.
PS> '10' - '2'
8
PS> '10' / '2'
5
Sebaliknya, operator + dan * memiliki semantik khusus string (perangkaian dan replikasi).
PS> '10' + '2'
102
PS> '10' * '2'
1010
Saat Anda menggunakan nilai Boolean dengan operator aritmatika, PowerShell mengonversi nilai menjadi bilangan bulat: $true menjadi [int]1 dan $false menjadi [int]0.
PS> $false - $true
-1
Satu pengecualian adalah perkalian (*) dari dua boolean.
PS> $false * $true
InvalidOperation: The operation '[System.Boolean] * [System.Boolean]' is not
defined.
Untuk jenis LHS lainnya, operator aritmatika hanya berhasil jika jenis tertentu mendefinisikan operator ini melalui operator kelebihan beban.
Operasi perbandingan
Operator perbandingan, seperti -eq, -lt, dan -gt, dapat membandingkan operan dari berbagai jenis. Perilaku non-string dan jenis non-primitif tergantung pada apakah jenis LHS mengimplementasikan antarmuka seperti IEquatable dan IComparable.
Operator perbandingan berbasis koleksi (-in dan -contains) melakukan per elemen -eq perbandingan hingga kecocokan ditemukan. Ini adalah setiap elemen individu dari operand koleksi yang mendorong paksaan jenis apa pun.
PS> $true -in 'true', 'false'
True
PS> 'true', 'false' -contains $true
True
Kedua contoh mengembalikan true karena 'true' -eq $true menghasilkan $true.
Untuk informasi selengkapnya, lihat about_Comparison_Operators.