Atama ve dönüştürmeler (F#)
Bu makalede F# dilinde tür dönüştürmeleri için destek açıklanmaktadır.
Aritmetik Türler
F# tamsayı ve kayan nokta türleri gibi çeşitli temel türler arasında aritmetik dönüştürmeler için dönüştürme işleçleri sağlar. İntegral ve karakter dönüştürme işleçleri formları denetlemiş ve işaretlenmemiş; kayan nokta işleçleri ve enum
dönüştürme işleci bunu yapmaz. İşaretsiz formlar içinde FSharp.Core.Operators
tanımlanır ve denetlenen formlar içinde FSharp.Core.Operators.Checked
tanımlanır. denetlenen formlar taşma olup olmadığını denetler ve sonuçta elde edilen değer hedef türün sınırlarını aşarsa bir çalışma zamanı özel durumu oluşturur.
Bu işleçlerin her biri hedef türün adıyla aynı ada sahiptir. Örneğin, türlerin açıkça açıklama eklendiği byte
aşağıdaki kodda iki farklı anlama sahip görünür. İlk oluşum türü, ikincisi dönüştürme işlecidir.
let x : int = 5
let b : byte = byte x
Aşağıdaki tabloda F# dilinde tanımlanan dönüştürme işleçleri gösterilmektedir.
Operator | Açıklama |
---|---|
byte |
8 bit imzasız bir tür olan bayt türüne dönüştürün. |
sbyte |
İmzalı bayta dönüştürün. |
int16 |
16 bit imzalı tamsayıya dönüştürün. |
uint16 |
16 bit işaretsiz tamsayıya dönüştürün. |
int32, int |
32 bit imzalı tamsayıya dönüştürün. |
uint32 |
32 bit işaretsiz tamsayıya dönüştürün. |
int64 |
64 bit imzalı tamsayıya dönüştürün. |
uint64 |
64 bit işaretsiz tamsayıya dönüştürün. |
nativeint |
Yerel bir tamsayıya dönüştürün. |
unativeint |
İşaretsiz yerel tamsayıya dönüştürün. |
float, double |
64 bit çift duyarlıklı IEEE kayan nokta sayısına dönüştürün. |
float32, single |
32 bit tek duyarlıklı IEEE kayan nokta numarasına dönüştürün. |
decimal |
öğesine System.Decimal dönüştürün. |
char |
unicode karakterine System.Char dönüştürün. |
enum |
Numaralandırılmış türe dönüştürün. |
Yerleşik ilkel türlere ek olarak, bu işleçleri veya uygun imzalara sahip yöntemleri uygulayan op_Explicit
op_Implicit
türlerle kullanabilirsiniz. Örneğin, dönüştürme işleci türü int
parametre olarak alan ve döndüren int
statik bir yöntem op_Explicit
sağlayan herhangi bir türle çalışır. Yöntemlerin dönüş türüne göre aşırı yüklenemeyeceği genel kuralın özel bir özel durumu olarak, bunu ve op_Implicit
için op_Explicit
yapabilirsiniz.
Numaralandırılmış Türler
enum
işleci, dönüştürülecek öğesinin türünü temsil eden bir tür enum
parametresi alan genel bir işleçtir. Numaralandırılmış bir türe dönüştürüldüğünde tür çıkarımı, dönüştürmek istediğiniz türü enum
belirlemeye çalışır. Aşağıdaki örnekte değişken col1
açıkça açıklama eklemez, ancak türü daha sonraki eşitlik testinden çıkarılır. Bu nedenle, derleyici bir Color
numaralandırmaya dönüştürdüğünüz sonucu verebilir. Alternatif olarak, aşağıdaki örnekte olduğu gibi col2
bir tür ek açıklaması sağlayabilirsiniz.
type Color =
| Red = 1
| Green = 2
| Blue = 3
// The target type of the conversion cannot be determined by type inference, so the type parameter must be explicit.
let col1 = enum<Color> 1
// The target type is supplied by a type annotation.
let col2 : Color = enum 2
Ayrıca, aşağıdaki kodda olduğu gibi hedef numaralandırma türünü açıkça tür parametresi olarak belirtebilirsiniz:
let col3 = enum<Color> 3
Numaralandırma atamalarının yalnızca sabit listesinin temel alınan türü dönüştürülen türle uyumluysa çalıştığını unutmayın. Aşağıdaki kodda, ve uint32
arasındaki int32
uyuşmazlık nedeniyle dönüştürme derlenemiyor.
// Error: types are incompatible
let col4 : Color = enum 2u
Daha fazla bilgi için bkz . Numaralandırmalar.
Nesne Türlerini Atama
Nesne hiyerarşisindeki türler arasında dönüştürme, nesne odaklı programlama için temeldir. İki temel dönüştürme türü vardır: yukarı dönüştürme (yukarı yayın) ve aşağı dönüştürme (downcasting). Hiyerarşiyi atama, türetilmiş bir nesne başvurusundan temel nesne başvurusuna dönüştürme anlamına gelir. Temel sınıf türetilmiş sınıfın devralma hiyerarşisinde olduğu sürece böyle bir atamanın çalışması garanti edilir. Temel nesne başvurusundan türetilmiş nesne başvurusuna bir hiyerarşinin dökümünün atılması, yalnızca nesnenin gerçekten doğru hedef (türetilmiş) türünün bir örneği veya hedef türden türetilmiş bir tür olması durumunda başarılı olur.
F# bu tür dönüştürmeler için işleçler sağlar. :>
işleci hiyerarşiyi oluşturur ve :?>
işleç hiyerarşiyi aşağı doğru yayınlar.
Yayına Alma
Nesne odaklı birçok dilde, yukarı yayın örtükdür; F# dilinde kurallar biraz farklıdır. Bir nesne türündeki yöntemlere bağımsız değişkenler geçirdiğinizde, yukarı yayın otomatik olarak uygulanır. Ancak, bir modüldeki let-bound işlevleri için, parametre türü esnek bir tür olarak bildirilmediği sürece, yukarı noktaya yayın otomatik değildir. Daha fazla bilgi için bkz . Esnek Türler.
işleci :>
statik bir atama gerçekleştirir, yani derleme zamanında atamanın başarısı belirlenir. Kullanan :>
bir atama başarıyla derleniyorsa, geçerli bir atamadır ve çalışma zamanında başarısız olma şansı yoktur.
Böyle bir dönüştürme gerçekleştirmek için işlecini upcast
de kullanabilirsiniz. Aşağıdaki ifade hiyerarşiyi bir dönüştürmeyi belirtir:
upcast expression
Upcast işlecini kullandığınızda, derleyici bağlamdan dönüştürdüğünüz türü çıkarsamaya çalışır. Derleyici hedef türü belirleyemezse, derleyici bir hata bildirir. Tür ek açıklaması gerekebilir.
Aşağı Yayın
işleci :?>
dinamik bir atama gerçekleştirir, yani atamanın başarısı çalışma zamanında belirlenir. işlecini :?>
kullanan bir atama derleme zamanında denetlenmiyor; ancak çalışma zamanında, belirtilen türe dönüştürme girişiminde bulunulması. Nesne hedef türle uyumluysa, atama başarılı olur. Nesne hedef türle uyumlu değilse, çalışma zamanı bir InvalidCastException
oluşturur.
Dinamik tür dönüştürmesi gerçekleştirmek için işlecini downcast
de kullanabilirsiniz. Aşağıdaki ifade, hiyerarşiyi program bağlamından çıkarmış bir türe dönüştürmeyi belirtir:
downcast expression
işlecine upcast
gelince, derleyici bağlamdan belirli bir hedef türü çıkaramıyorsa bir hata bildirir. Tür ek açıklaması gerekebilir.
Aşağıdaki kod, ve :?>
işleçlerinin :>
kullanımını gösterir. Kod, dönüştürmenin :?>
başarılı olacağını bildiğinizde işlecin en iyi şekilde kullanıldığını gösterir, çünkü dönüştürme başarısız olursa oluşturulur InvalidCastException
. Dönüştürmenin başarılı olacağını bilmiyorsanız, özel durum oluşturma yükünü önlediğinden ifade kullanan bir match
tür testi daha iyidir.
type Base1() =
abstract member F : unit -> unit
default u.F() =
printfn "F Base1"
type Derived1() =
inherit Base1()
override u.F() =
printfn "F Derived1"
let d1 : Derived1 = Derived1()
// Upcast to Base1.
let base1 = d1 :> Base1
// This might throw an exception, unless
// you are sure that base1 is really a Derived1 object, as
// is the case here.
let derived1 = base1 :?> Derived1
// If you cannot be sure that b1 is a Derived1 object,
// use a type test, as follows:
let downcastBase1 (b1 : Base1) =
match b1 with
| :? Derived1 as derived1 -> derived1.F()
| _ -> ()
downcastBase1 base1
Genel işleçler downcast
bağımsız upcast
değişkeni ve dönüş türünü belirlemek için tür çıkarımına bağlı olduğundan, önceki kod örneğinde değerini ile let base1: Base1 = upcast d1
değiştirebilirsinizlet base1 = d1 :> Base1
.
Kendi başına temel sınıfı belirleyemediğinden upcast
tür ek açıklaması gereklidir.
Örtük yukarı yayın dönüştürmeleri
Örtük yukarı yayınlar aşağıdaki durumlarda eklenir:
Bilinen bir adlandırılmış türe sahip bir işleve veya yönteme parametre sağlarken. Hesaplama ifadeleri veya dilimleme gibi bir yapı bir yöntem çağrısına dönüştüğünde buna dahildir.
Bilinen adlandırılmış türe sahip bir kayıt alanına veya özelliğe atama veya özelliği kapatma.
Bir veya
match
ifadesininif/then/else
dalı başka bir daldan veya genel olarak bilinen türden kaynaklanan bilinen bir hedef türüne sahip olduğunda.Liste, dizi veya dizi ifadesinin bir öğesi bilinen bir hedef türüne sahip olduğunda.
Örneğin, aşağıdaki kodu göz önünde bulundurun:
open System
open System.IO
let findInputSource () : TextReader =
if DateTime.Now.DayOfWeek = DayOfWeek.Monday then
// On Monday a TextReader
Console.In
else
// On other days a StreamReader
File.OpenText("path.txt")
Burada, sırasıyla a TextReader
ve StreamReader
koşullu işleminin dalları. İkinci dalda, bilinen hedef türü yöntemindeki tür ek açıklamasından ve ilk daldandır TextReader
. Bu, ikinci dalda yukarı yayın gerek olmadığı anlamına gelir.
Ek örtük bir yukarı yayının kullanıldığı her noktada uyarı göstermek için 3388 uyarısını (/warnon:3388
veya özelliğini <WarnOn>3388</WarnOn>
) etkinleştirebilirsiniz.
Örtük sayısal dönüştürmeler
F# çoğu durumda dönüştürme işleçleri aracılığıyla sayısal türlerin açıkça genişletilmesi kullanır. Örneğin, veya int16
gibi int8
sayısal türlerin çoğu için veya kaynak float32
float64
ya da hedef türü bilinmediğinde açık genişletme gerekir.
Ancak örtük yukarı yayınlarla aynı durumlarda, 64 bit tamsayılara genişletilen 32 bit tamsayılar için örtük genişletmeye izin verilir. Örneğin, tipik bir API şeklini göz önünde bulundurun:
type Tensor(…) =
static member Create(sizes: seq<int64>) = Tensor(…)
int64 için tamsayı değişmez değerleri kullanılabilir:
Tensor.Create([100L; 10L; 10L])
Veya int32 için tamsayı değişmez değerleri:
Tensor.Create([int64 100; int64 10; int64 10])
Tür çıkarımı sırasında hem kaynak hem de hedef türü bilindiğinde, için için , ile ve double
için genişletme otomatik nativeint
int64
int32
int32
olarak gerçekleşir.int32
Bu nedenle, önceki örnekler gibi durumlarda değişmez int32
değerler kullanılabilir:
Tensor.Create([100; 10; 10])
Ayrıca, örtük sayısal genişletmenin kullanıldığı her noktada uyarı göstermek için isteğe bağlı olarak 3389 (/warnon:3389
veya özelliği <WarnOn>3389</WarnOn>
) uyarısını etkinleştirebilirsiniz.
. NET stili örtük dönüştürmeler
.NET API'leri, statik yöntemlerin tanımlarının op_Implicit
türler arasında örtük dönüştürmeler sağlamasına olanak sağlar. Bunlar, bağımsız değişkenler yöntemlere geçirilirken F# kodunda otomatik olarak uygulanır. Örneğin, yöntemlere açık çağrılar op_Implicit
yapan aşağıdaki kodu göz önünde bulundurun:
open System.Xml.Linq
let purchaseOrder = XElement.Load("PurchaseOrder.xml")
let partNos = purchaseOrder.Descendants(XName.op_Implicit "Item")
. Net stili op_Implicit
dönüştürmeler, kaynak ifade ve hedef tür için türler kullanılabilir olduğunda bağımsız değişken ifadeleri için otomatik olarak uygulanır:
open System.Xml.Linq
let purchaseOrder = XElement.Load("PurchaseOrder.xml")
let partNos = purchaseOrder.Descendants("Item")
Ayrıca isteğe bağlı olarak 3395 uyarısını (/warnon:3395
veya özelliğini <WarnOn>3395</WarnOn>
) etkinleştirerek her noktada bir uyarı gösterebilirsiniz. NET stili örtük dönüştürme kullanılır.
. NET stili op_Implicit
dönüştürmeler, örtük yukarı yayınlarla aynı durumlarda yöntem bağımsız değişken olmayan ifadeler için de otomatik olarak uygulanır. Ancak, yaygın veya uygunsuz bir şekilde kullanıldığında örtük dönüştürmeler tür çıkarımıyla kötü etkileşimde bulunabilir ve anlaşılması daha zor olan kodlara yol açabilir. Bu nedenle, bunlar bağımsız değişken olmayan konumlarda kullanıldığında her zaman uyarı oluşturur.
Bir öğesinin her noktasında bir uyarı göstermek için. NET stili örtük dönüştürme, yöntem dışı bir bağımsız değişken için kullanılır; uyarı 3391 'i (/warnon:3391
veya özelliğini <WarnOn>3391</WarnOn>
) etkinleştirebilirsiniz.
Dönüştürmelerle ilgili uyarıların özeti
Örtük dönüştürmelerin kullanımları için aşağıdaki isteğe bağlı uyarılar sağlanır:
/warnon:3388
(ek örtük yukarı yayın)/warnon:3389
(örtük sayısal genişletme)/warnon:3391
(op_Implicit
yöntem dışı bağımsız değişkenlerde, varsayılan olarak açık)/warnon:3395
(op_Implicit
yöntem bağımsız değişkenlerinde)