在Kotlin中,一切都是对象,因此我们可以在任何变量上调用对象的成员函数和属性。一些类型可以有特殊的内部表示例如,数字、字符和布尔值可以在运行时表示为原始值,但对用户来说,它们看起来像普通的类。为什么这些类型会在运行时被表示为原始类型呢?因为用引用类型去代替基本数据类型效率是很低。在本节中,我们将描述Kotlin中使用的基本类型:数字、布尔值、字符、字符串和数组。Numbers(包括整数类型和浮点类型) 整数类型(包括Byte、Short、Int、Long) Kotlin提供了一组表示数字的内置类型。对于整数,有四种不同大小的类型,因此也有不同的取值范围。 类型 大小(位) 最小值 最大值 Byte 8hr128 127hrShort 16hr32768 32767hrInt 32hr2,147,483,648() 2,147,483,647() Long 649,223,372,036,854,775,808 ()9,223,372,036,854,775,807 () 在使用整数类型初始化变量的时候,如果初始值不超过Int类型最大值,那么所有变量都具有推断类型Int。如果初始值超过此值,则推断类型为Long。要显式指定Long值,请将后缀附加L到值。valone1Int(字面常量在Int范围内,变量的类型推断为Int)valthreeBillion3000000000Long(字面常量超过了Int范围,推断类型为Long)valoneLong1LLong(字面常量显式指定了类型为Long)valoneByte:Byte1(变量类型直接指定为Byte类型) 浮点类型(包括Float、Double) 对于实数,Kotlin提供浮点类型Float和Double。根据IEEE754标准,浮点类型的区别在于它们的小数位不同,即它们可以存储多少位小数。 Type Size(bits) Significantbits Exponentbits Decimaldigits Float 32hr24hr8hr67 Double 64hr53hr11hr1516 您可以使用具有小数部分的数字来初始化Float和Double变量。对于用小数初始化的变量,编译器会推断Double类型。valoneDouble1。0Doublevalone:Double1Error:typemismatch(声明了是Double类型,但是字面常量是整数类型) 要显式给Float类型的变量指定值,需要给初始值添加后缀f或F。如果初始值包含超过67位小数位数,它将被四舍五入。vale2。7182818284DoublevaleFloat2。7182818284fFloat,actualvalueis2。7182817valoneFloat:Float2。7182818284Error:typemismatch(变量是float,但是字面常量是double)valoneDouble:Double2。7182818284fError:typemismatch(变量是Double,但是字面常量是float) 字面常量 整数值有以下几种字面常量:十进制:123(Long类型写L标记:123)十六进制:0x0F二进制文件:0b00001011注意:不支持八进制 浮点值有以下几种字面常量:默认是Double类型:123。5,123。5e10Float类型由f或F标记:123。5f 可以使用下划线使数字常量更具可读性:valoneMillion1000000valcreditCardNumber1234567890123456LvalsocialSecurityNumber999999999LvalhexBytes0xFFECDE5Evalbytes0b11010010011010011001010010010010 显式转换 由于表示方式不同,较小的类型不是较大类型的子类型。如果是这样,我们将遇到以下问题:假设的代码,实际上不能编译:vala:Int?1一个装箱的Int类型(java。lang。Integer)valb:Long?a隐式转换生成一个已装箱的Long(java。lang。Long)print(ba)这个函数输出false,因为Long的equals()会检查另一个参数是否也是Long。 因此,较小的类型不会隐式转换为较大的类型。这意味着将类型值分配给Byte变量Int需要显式转换。valb:Byte1OK,literalsarecheckedstaticallyvali:IntbERRORvali1:Intb。toInt() 所有数字类型都支持转换为其他类型:toByte():BytetoShort():ShorttoInt():InttoLong():LongtoFloat():FloattoDouble():DoubletoChar():Char 有些情况下也是可以使用自动类型转化的,前提是可以根据上下文环境推断出正确的数据类型而且数学操作符会做相应的重载。例如下面是正确的:vall1L3LongIntLong 运算 Kotlin支持标准的数字算术运算集:,,,,。它们被声明为相应类的成员。您还可以为自定义类覆盖这些运算符。有关详细信息,请参阅运算符重载。println(12)println(2500000000L1L)println(3。142。71)println(10。03) 整数除法 整数之间的除法总是返回一个整数。任何小数部分都将被丢弃。valx52println(x2。5)ERROR:OperatorcannotbeappliedtoIntandDoubleprintln(x2) 位运算 Kotlin提供了一组对整数的按位运算。它们直接在数字表示的二进制位上进行操作。但对于位运算,没有特殊字符来表示,只能用中缀函数表示,它们只能应用于Int和Long。valx(1shl2)and0x000FF000 以下是按位运算的完整列表:shl(bits)有符号左移shr(bits)有符号右移ushr(bits)无符号右移and(bits)按位和or(bits)按位或xor(bits)按位异或inv()位反转布尔值 布尔用Boolean类型表示,它有两个值:true和false。若需要可空引用布尔会被装箱。内置的布尔运算有:短路逻辑或短路逻辑与!逻辑非字符 字符类型由Char表示。字符文字放在单引号中:1。特殊字符可以用反斜杠转义,持以下转义序列:,b,,r,,,和。要对任何其他字符进行编码,请使用Unicode转义序列语法:。当需要可空引用时,像数字、字符会被装箱。装箱操作不会保留同一性。valaChar:Charaprintln(aChar)println()printsanextranewlinecharacterprintln()字符串 Kotlin中的字符串类型由String表示。通常,字符串值是双引号()中的字符序列。字符串的元素是字符,您可以通过索引操作访问:s〔i〕。也可以使用循环遍历这些字符for:for(cinstr){println(c)} 字符串是不可变的。初始化字符串后,您将无法更改其值或为其分配新值。所有改变字符串的操作都在一个新String对象中返回它们的结果,而原始字符串保持不变。valstrabcdprintln(str。uppercase())CreateandprintanewStringobjectprintln(str)theoriginalstringremainsthesame 要连接字符串,请使用运算符。这也适用于将字符串与其他类型的值连接,只要表达式中的第一个元素是字符串:valsabc1println(sdef) 请注意,在大多数情况下,使用字符串模板或原始字符串优于字符串连接。 字符串字面量 Kotlin有两种类型的字符串文字:可能包含转义字符的转义字符串可以包含换行符和任意文本的原始字符串 这是一个转义字符串的示例:valsHello,world! 原始字符串由三引号()分隔,不包含转义,并且可以包含换行符和任何其他字符:valtextfor(cinfoo)print(c) 要从原始字符串中删除前导空格,请使用以下trimMargin()函数:valtextTellmeandIforget。TeachmeandIremember。InvolvemeandIlearn。(BenjaminFranklin)。trimMargin() 默认情况下,用作边距前缀,但您可以选择另一个字符并将其作为参数传递,例如trimMargin()。 字符串模板 字符串可以包含模板表达式,即一些小段代码,会求值并把结果合并到字符串中。模板表达式以美元符()开头,由一个简单的名字构成:vali10println(ii)printsi10 或者用花括号扩起来的任意表达式:valsabcprintln(s。lengthis{s。length})printsabc。lengthis3 原生字符串和转义字符串内部都支持模板。如果你需要在原生字符串中表示字面值字符(它不支持反斜杠转义),你可以用下列语法:valprice{39;}9。99数组 Kotlin中的数组由Array类表示,并且还有一个size属性及get和set方法,由于使用〔〕重载了get和set方法,所以我们可以通过下标很方便地获取或者设置数组对应位置的值。classArrayTprivateconstructor(){valsize:Intoperatorfunget(index:Int):Toperatorfunset(index:Int,value:T):Unitoperatorfuniterator():IteratorT。。。} 数组的创建有两种方式:一种是使用函数arrayOf();另外一种是使用工厂函数。如下所示,我们分别是两种方式创建了两个数组:〔1,2,3〕valaarrayOf(1,2,3)〔0,2,4〕valbArray(3,{i(i2)})读取数组内容println(a〔0〕)输出结果:1println(b〔1〕)输出结果:2 正如我们上面所说,该〔〕操作代表对成员函数的调用get()和set()。Kotlin中的数组是不变的。这意味着Kotlin不允许我们将Array分配给Array,这可以防止可能的运行时失败(但您可以使用Array,请参阅TypeProjections)。 原始类型数组 Kotlin也有表示基本类型数组,省去了装箱操作,因此效率更高:ByteArray、ShortArray、IntArray等等。这些类与Array类没有继承关系,但它们具有相同的方法和属性集。它们中的每一个也都有对应的工厂函数:valx:IntArrayintArrayOf(1,2,3)x〔0〕x〔1〕x〔2〕Arrayofintofsize5withvalues〔0,0,0,0,0〕valarrIntArray(5)e。g。initialisethevaluesinthearraywithaconstantArrayofintofsize5withvalues〔42,42,42,42,42〕valarrIntArray(5){42}e。g。initialisethevaluesinthearrayusingalambdaArrayofintofsize5withvalues〔0,1,2,3,4〕(valuesinitialisedtotheirindexvalue)vararrIntArray(5){it1}