Atama ve dönüştürmeler (F #)
Bu makalede F # içindeki tür dönüştürmeleri için destek açıklanır.
Aritmetik türler
F #, tamsayı ve kayan nokta türleri arasındaki 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 Char dönüştürme işleçleri denetlenen ve Denetlenmemiş formlara sahiptir; kayan nokta işleçleri ve enum dönüştürme işleci değildir. Denetlenmemiş Formlar ' de tanımlanmıştır FSharp.Core.Operators ve denetlenen formlarda ' de tanımlanmıştır FSharp.Core.Operators.Checked . Denetlenen formlar taşma durumunu denetler ve 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ün adı ile aynı ada sahiptir. Örneğin, aşağıdaki kodda, türlerin açıkça açıklandığı, byte iki farklı anlam ile görünür. İlk oluşum türdür, ikincisi ise dönüştürme işleçtir.
let x : int = 5
let b : byte = byte x
Aşağıdaki tabloda F # içinde tanımlanan dönüştürme işleçleri gösterilmektedir.
| İşleç | Açıklama |
|---|---|
byte |
8 bit işaretsiz bir tür bayta Dönüştür. |
sbyte |
İşaretli bayta Dönüştür. |
int16 |
16 bit işaretli tamsayıya Dönüştür. |
uint16 |
16 bit işaretsiz tamsayıya Dönüştür. |
int32, int |
32 bitlik işaretli tamsayıya Dönüştür. |
uint32 |
32 bitlik işaretsiz tamsayıya Dönüştür. |
int64 |
64 bitlik işaretli tamsayıya Dönüştür. |
uint64 |
64 bitlik işaretsiz tamsayıya Dönüştür. |
nativeint |
Yerel tamsayıya Dönüştür. |
unativeint |
İşaretsiz yerel tamsayıya Dönüştür. |
float, double |
64 bitlik bir çift duyarlıklı IEEE kayan noktalı sayıya dönüştürün. |
float32, single |
32 bitlik tek duyarlıklı bir IEEE kayan noktalı sayıya dönüştürün. |
decimal |
Öğesine Dönüştür System.Decimal . |
char |
System.CharUnicode karaktere Dönüştür. |
enum |
Numaralandırılmış bir türe Dönüştür. |
Yerleşik temel türlerin yanı sıra, bu işleçleri, op_Explicit veya op_Implicit uygun imzalara sahip Yöntemler uygulayan türlerle birlikte kullanabilirsiniz. Örneğin, int dönüştürme işleci, op_Explicit türü parametre olarak alan ve döndüren statik bir yöntem sağlayan herhangi bir tür ile birlikte kullanılır int . Genel kurala özel bir özel durum olarak, metotları dönüş türü tarafından aşırı yüklenemez, ve için bunu yapabilirsiniz op_Explicit op_Implicit .
Numaralandırılmış türler
enumİşleci, dönüştürülecek öğesinin türünü temsil eden bir tür parametresi alan genel bir işleçtir enum . Numaralandırılmış bir türe dönüşürse, dönüştürmek istediğiniz öğesinin türünü belirlemekte çıkarım denemeleri yazın enum . Aşağıdaki örnekte, değişkeni col1 açıkça açıklama eklenmiş değildir, ancak türü daha sonraki eşitlik testinde çıkarsanamıyor. Bu nedenle, derleyici bir numaralandırmaya dönüştürmekte olduğunuz tarafından ortaya çıkarılamıyor Color . Alternatif olarak, aşağıdaki örnekte olduğu gibi bir tür ek açıklaması sağlayabilirsiniz col2 .
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
Hedef numaralandırma türünü, aşağıdaki kodda olduğu gibi açıkça bir tür parametresi olarak da belirtebilirsiniz:
let col3 = enum<Color> 3
Sabit listesinin, yalnızca Numaralandırmadaki temeldeki tür, dönüştürülmekte olan türle uyumluysa çalıştığını unutmayın. Aşağıdaki kodda, ve arasındaki uyuşmazlığın nedeniyle dönüştürme derlenemiyor int32 uint32 .
// 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 temel bir nesnedir. İki temel dönüştürme türü vardır: atama (yukarı atama) ve (aşağı atama). Bir hiyerarşiyi atama, türetilmiş bir nesne başvurusundan bir temel nesne başvurusuna atama anlamına gelir. Bu tür bir dönüştürme, temel sınıf türetilmiş sınıfın devralma hiyerarşisinde olduğu sürece çalışma garantisi verir. Bir hiyerarşiyi, bir temel nesne başvurusundan türetilmiş bir nesne başvurusuna dönüştürme işlemi, yalnızca nesne doğru hedef (türetilen) türünün bir örneği veya hedef türünden türetilmiş bir tür olduğunda başarılı olur.
F # Bu dönüştürme türleri için işleçler sağlar. :>İşleci hiyerarşiyi yayınlar ve :?> operatör hiyerarşiyi aşağı yayınlar.
Yukarı atama
Birçok nesne yönelimli dilde, yukarı atama örtük bir şekilde; F # ' da, kurallar biraz farklıdır. Bağımsız değişkenleri bir nesne türündeki yöntemlere geçirdiğinizde, upatama otomatik olarak uygulanır. Ancak, bir modüldeki izin-sınırlı işlevler için, parametre türü esnek bir tür olarak bildirilemediği sürece, UPI otomatik değildir. Daha fazla bilgi için bkz. Esnek türler.
:>İşleci statik bir atama gerçekleştirir, bu, dönüştürmenin başarısı derleme zamanında belirlendiği anlamına gelir. Kullanan bir tür :> başarıyla derleniyorsa, bu geçerli bir tür ve çalışma zamanında hata şansı yoktur.
upcastBu tür bir dönüştürme gerçekleştirmek için işlecini de kullanabilirsiniz. Aşağıdaki ifade hiyerarşinin bir dönüşümünü belirtir:
upcast expression
Upcast işlecini kullandığınızda, derleyici, bağlamındaki dönüştürmekte olduğunuz türü çıkarmakta çalışır. Derleyici hedef türünü tespit leyemiyorsa, derleyici bir hata bildirir. Tür ek açıklaması gerekli olabilir.
Alta çevrim
:?>İşleci dinamik bir atama gerçekleştirir, bu, dönüştürmenin başarısı çalışma zamanında belirlendiği anlamına gelir. İşleci kullanan bir tür :?> derleme zamanında denetlenmez; ancak çalışma zamanında, belirtilen türe atama için bir deneme yapılır. Nesne hedef türle uyumluysa, atama başarılı olur. Nesne hedef türle uyumlu değilse, çalışma zamanı bir oluşturur InvalidCastException .
downcastDinamik bir tür dönüştürmesi gerçekleştirmek için işlecini de kullanabilirsiniz. Aşağıdaki ifade, hiyerarşinin bir program bağlamından çıkarılan bir türe dönüştürülmesini belirtir:
downcast expression
upcastİşleci olarak, derleyici bağlamdan belirli bir hedef türü çıkarsanamıyor bir hata bildirir. Tür ek açıklaması gerekli olabilir.
Aşağıdaki kod, :> ve işleçlerinin kullanımını gösterir :?> . Kod, dönüştürmenin :?> başarılı olacağını bildiğiniz zaman, InvalidCastException dönüştürmenin başarısız olup olmadığını belirten işlecin en iyi şekilde kullanıldığını gösterir. Dönüştürmenin başarılı olacağını görmüyorsanız, bir ifade kullanan bir tür testi match daha iyidir, çünkü özel durum oluşturma ek yükünü önler.
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
downcast upcast Bağımsız değişkeni ve dönüş türünü belirleyebilmek için genel işleçler ve tür çıkarımı kullandığından, let base1 = d1 :> Base1 önceki kod örneğinde öğesini ile değiştirebilirsiniz let base1: Base1 = upcast d1 .
Bir tür ek açıklaması gerekir, çünkü upcast kendisi tarafından temel sınıf saptanamadı.
Örtük upcast dönüştürmeleri
Örtük ön yayınlar aşağıdaki durumlara eklenir:
Bir işleve veya yöntemine bilinen adlandırılmış türe sahip bir parametre sağlarken. Bu, hesaplama ifadeleri veya Dilimleme gibi bir yapının Yöntem çağrısı haline geldiğini içerir.
Bir kayıt alanı veya özellik, bilinen bir adlandırılmış türü olan bir veya daha fazla değişikliğe göre.
if/then/elseOr ifadesinin bir dalımatch, başka bir daldan veya genel olarak bilinen türden doğan bilinen bir hedef türüne sahip olduğunda.List, array veya Sequence 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 ve sırasıyla koşullu işlem dalları TextReader StreamReader . İkinci dalda, bilinen hedef türü TextReader yöntemdeki tür ek açıklamasına ve ilk daldan olur. Bu, ikinci dalda hiçbir dönüştürme gerekmediği anlamına gelir.
Her noktada bir uyarı göstermek için ek bir örtük yukarı dönüştürme kullanılır, uyarı 3388 ' i ( /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 bir şekilde genişleyen kullanımını kullanır. Örneğin, ya da ya da ya int8 int16 da ya float32 float64 da kaynak ya da hedef türü bilinmiyor gibi çoğu sayısal tür için açık genişletme gerekir.
Ancak, 32 bitlik tamsayılar için örtük genişletme, iletildiklerinde ile 64 bit tamsayılar için izin verilir ve bu durumda örtük bir şekilde yapılır. Örneğin, tipik bir API şeklini göz önünde bulundurun:
type Tensor(…) =
static member Create(sizes: seq<int64>) = Tensor(…)
Int64 için tamsayı sabit değerleri kullanılabilir:
Tensor.Create([100L; 10L; 10L])
Ya da Int32 için tamsayı değişmez değerleri:
Tensor.Create([int64 100; int64 10; int64 10])
int32 int64 int32 nativeint int32 double Hem kaynak hem de hedef türü tür çıkarımı sırasında bilindiğinde, için genişletme otomatik olarak yapılır. Bu nedenle, önceki örnekler gibi durumlarda int32 değişmez değerler kullanılabilir:
Tensor.Create([100; 10; 10])
Ayrıca, isteğe bağlı olarak, uyarı 3389 ' /warnon:3389 i (veya özelliği <WarnOn>3389</WarnOn> ) her bir noktada bir uyarı gösterecek şekilde etkinleştirebilirsiniz.
. NET stili örtük dönüştürmeler
.NET API'leri, op_Implicit türler arasında örtülü dönüştürmeler sağlamak için statik yöntemlerin tanımına olanak sağlar. Bunlar, yöntemlere bağımsız değişkenler geçerken F# kodunda otomatik olarak uygulanır. Örneğin, yöntemlere açık çağrılar yapan aşağıdaki kodu op_Implicit göz önünde bulundurabilirsiniz:
open System.Xml.Linq
let purchaseOrder = XElement.Load("PurchaseOrder.xml")
let partNos = purchaseOrder.Descendants(XName.op_Implicit "Item")
. Net stili dönüştürmeler, kaynak ifade ve hedef tür için türler kullanılabilir olduğunda op_Implicit 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 ( veya özelliği ) uyarıyı etkinleştirarak bir noktasının /warnon:3395 her noktasında bir uyarı <WarnOn>3395</WarnOn> gösterabilirsiniz. NET stili örtülü dönüştürme kullanılır.
. NET stili dönüştürmeler, örtülü yukarı yayınlarla aynı durumlarda yöntem dışı bağımsız değişken op_Implicit ifadeleri için de otomatik olarak uygulanır. Ancak, yaygın veya uygunsuz bir şekilde kullanılırken, örtülü dönüştürmeler tür çıkarlığıyla kötü etkileşime sızabilir ve an zor olan kodlara yol açabilir. Bu nedenle, bunlar bağımsız değişken olmayan konumlarda kullanılırken her zaman uyarılar üretir.
Bir olan her noktada bir uyarı göstermek için. NET stili örtülü dönüştürme yöntem olmayan bir bağımsız değişken için kullanılır; 3391 ( veya özelliği) /warnon:3391 uyarılarını <WarnOn>3391</WarnOn> etkinleştirebilirsiniz.
Dönüştürmelerle ilgili uyarıların özeti
Örtülü dönüştürmelerin kullanımları için aşağıdaki isteğe bağlı uyarılar sağlanır:
/warnon:3388(ek örtülü yukarı yayın)/warnon:3389(örtülü sayısal genişle)/warnon:3391(op_Implicitmetot dışı bağımsız değişkenlerde, varsayılan olarak açıktır)/warnon:3395(op_Implicitmetot bağımsız değişkenlerde)