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.Checkedtanı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.Decimaldönüştürün.
char unicode karakterine System.Chardö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_Explicitop_Implicit türlerle kullanabilirsiniz. Örneğin, dönüştürme işleci türü int parametre olarak alan ve döndüren intstatik 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_Implicitiç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 uint32arası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 InvalidCastExceptionoluş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 d1değ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 ifadesinin if/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 int16gibi int8 sayısal türlerin çoğu için veya kaynak float32float64ya 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 doubleiçin genişletme otomatik nativeintint64int32int32 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.

Ö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)

Ayrıca bkz.