我不确定Kotlin中IntArray
和Array<Int>
之间的区别是什么以及为什么我无法互换使用它们:
我知道IntArray
在定位int[]
时转化为JVM
,但Array<Int>
转化为什么?
此外,您还可以拥有String[]
或YourObject[]
。为什么Kotlin具有类型为{primitive}Array
的类,而几乎任何东西都可以排列成数组,而不仅仅是基元。
答案 0 :(得分:57)
Array<Int>
是一个Integer[]
,IntArray
是int[]
。那就是它。
这意味着,当您将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