Kotlin中的IntArray与Array <int>

时间:2017-07-13 21:00:43

标签: kotlin

我不确定Kotlin中IntArrayArray<Int>之间的区别是什么以及为什么我无法互换使用它们:

missmatch

我知道IntArray在定位int[]时转化为JVM,但Array<Int>转化为什么?

此外,您还可以拥有String[]YourObject[]。为什么Kotlin具有类型为{primitive}Array的类,而几乎任何东西都可以排列成数组,而不仅仅是基元。

3 个答案:

答案 0 :(得分:57)

Array<Int>是一个Integer[]IntArrayint[]。那就是它。

这意味着,当您将Int放入Array<Int>时,它将始终被加框(具体而言,通过Integer.valueOf()调用)。在IntArray的情况下,不会发生装箱,因为它会转换为Java原始数组。

除了上述可能的性能影响之外,还可以考虑方便。原始数组可以保持未初始化状态,并且在所有索引处都具有默认的0值。这就是IntArray和其他原始数组具有仅采用大小参数的构造函数的原因:

val arr = IntArray(10)
println(arr.joinToString()) // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0

相比之下,Array<T>没有一个只接受一个size参数的构造函数:它需要所有索引上的有效非空T个实例在创建后处于有效状态。对于Number类型,这可能是默认0,但无法创建任意类型T的默认实例。

因此,在创建Array<Int>时,您可以使用带有初始化函数的构造函数:

val arr = Array<Int>(10) { index -> 0 }  // full, verbose syntax
val arr = Array(10) { 0 }                // concise version

或者创建Array<Int?>以避免必须初始化每个值,但是每次从数组中读取时,您将被迫处理可能的null值。

val arr = arrayOfNulls<Int>(10)

答案 1 :(得分:2)

值得注意的是,在class procedure TMyType.HTTPRIO1AfterExecute(const MethodName: string; SOAPResponse: TStream); var List: TStringList; begin List := TStringList.Create(); try SOAPResponse.Position := 0; List.LoadFromStream(SOAPResponse); List.SaveToFile('response.xml'); finally List.Free(); end; end; function AFaturaOlustur(const Input: TFaturaOlusturInput; const GidenBelgeFormati: TGidenBelgeFormatlari; const GidenDosya, GelenDosya: string): Boolean; var RIO: THTTPRIO; WS: EarsivWebService; Request: faturaOlustur; Response: faturaOlusturResponse; Json: RawUTF8; begin if not TFile.Exists(GidenDosya) then begin LastError := 'AFaturaOlustur(): GidenDosya mevcut değil!'; end; RIO := THTTPRIO.Create(nil); RIO.OnAfterExecute := TMyType.HTTPRIO1AfterExecute; RIO.URL := URLEArsivFatura; WS := (RIO as EarsivWebService); SetSecurityHeader(WS); Json := RecordSaveJSON(Input, TypeInfo(TFaturaOlusturInput)); Request := nil; Response := nil; try Request := faturaOlustur.Create(); Request.input := string(Json); Request.fatura := belge.Create(); case GidenBelgeFormati of UBL: Request.fatura.belgeFormati := belgeFormatiEnum.UBL; CSXML: Request.fatura.belgeFormati := belgeFormatiEnum.CSXML; HTML: Request.fatura.belgeFormati := belgeFormatiEnum.HTML; PDF: Request.fatura.belgeFormati := belgeFormatiEnum.PDF; CUSTOM: Request.fatura.belgeFormati := belgeFormatiEnum.CUSTOM; PDF_CUSTOM: Request.fatura.belgeFormati := belgeFormatiEnum.PDF_CUSTOM; PDF_UBL: Request.fatura.belgeFormati := belgeFormatiEnum.PDF_UBL; CSXML1: Request.fatura.belgeFormati := belgeFormatiEnum.CSXML1; CSXML2: Request.fatura.belgeFormati := belgeFormatiEnum.CSXML2; CSXML3: Request.fatura.belgeFormati := belgeFormatiEnum.CSXML3; PDF_CSXML1: Request.fatura.belgeFormati := belgeFormatiEnum.PDF_CSXML1; PDF_CSXML2: Request.fatura.belgeFormati := belgeFormatiEnum.PDF_CSXML2; PDF_CSXML3: Request.fatura.belgeFormati := belgeFormatiEnum.PDF_CSXML3; end; Request.fatura.belgeIcerigi := ToByteDynArray(TFile.ReadAllBytes(GidenDosya)); try Response := WS.faturaOlustur(Request); except on E: Exception do begin LastError := 'AFaturaOlustur(): ' + E.Message; Exit(False); end; end; Result := Assigned(Response.return); if Result then Result := Response.return.resultCode = rcSuccess; if Result then begin TFile.WriteAllBytes(GelenDosya, ToBytes(Response.output.belgeIcerigi)); end else begin LastError := 'AFaturaOlustur(): ' + Response.return.resultText; end; finally Request.Free(); Response.Free(); end; end; 上使用传播(*)运算符将返回vararg。如果您需要IntArray,则可以使用Array<Int>来转换IntArray

答案 2 :(得分:1)

Kotlin中的数组是类(不是&#34;特殊&#34;类似Java的类型)。

Kotlin的stdlib为JVM原始数组提供了特殊用途类,以便改进Java语言集成和性能。

经验法则是使用Array<T>,除非它在与现有Java代码混合时引起问题,或者应该从Java类调用。为了记录,我从来没有使用IntArray

您可以在此处查看有关此事项的语言文档:https://kotlinlang.org/docs/reference/basic-types.html#arrays