kotlin常用语法

函数定义使用关键字fun,参数格式为:参数:类型

funsum(a:Int,b:Int):Int{returna+b}funprint(a:Int,b:Int):Unit{println(a+b)}可变长参数函数函数的变长参数可以用vararg关键字进行标识:

funvars(varargv:Int){for(vtinv){print(vt)}}//测试funmain(args:Array){vars(1,2,3,4,5)//输出12345}lambda(匿名函数)lambda表达式使用实例:

//测试funmain(args:Array){valsumLambda:(Int,Int)->Int={x,y->x+y}println(sumLambda(1,2))//输出3}定义常量与变量可变变量定义:var关键字

var<标识符>:<类型>=<初始化值>不可变变量定义:val关键字,只能赋值一次的变量(类似Java中final修饰的变量)

val<标识符>:<类型>=<初始化值>常量与变量都可以没有初始化值,但是在引用前必须初始化

//类型后面加表示可为空varage:String="23"//抛出空指针异常valages=age!!.toInt()//不做处理返回nullvalages1=age.toInt()//age为空返回-1valages2=age.toInt():-1类型检测及自动类型转换重点:做过类型检测之后,obj会自动被系统转换为String类型我们可以使用is运算符检测一个表达式是否某类型的一个实例(类似于Java中的instanceof关键字)。

fungetStringLength(obj:Any):Int{if(objisString){//做过类型判断以后,obj会被系统自动转换为String类型returnobj.length}//在这里还有一种方法,与Java中instanceof不同,使用!is//if(obj!isString){////XXX//}//这里的obj仍然是Any类型的引用returnnull}或者

fungetStringLength(obj:Any):Int{if(obj!isString)returnnull//在这个分支中,`obj`的类型会被自动转换为`String`returnobj.length}甚至还可以

fungetStringLength(obj:Any):Int{//在`&&`运算符的右侧,`obj`的类型会被自动转换为`String`if(objisString&&obj.length>0)returnobj.lengthreturnnull}区间区间表达式由具有操作符形式..的rangeTo函数辅以in和!in形成。

区间是为任何可比较类型定义的,但对于整型原生类型,它有一个优化的实现。以下是使用区间的一些示例:

for(iin1..4)print(i)//输出“1234”for(iin4..1)print(i)//什么都不输出if(iin1..10){//等同于1<=i&&i<=10println(i)}//使用step指定步长for(iin1..4step2)print(i)//输出“13”for(iin4downTo1step2)print(i)//输出“42”//使用until函数排除结束元素for(iin1until10){//iin[1,10)排除了10println(i)}kotlin基本数据类型比较2个数字Kotlin中没有基础数据类型,只有封装的数字类型,你每定义的一个变量,其实Kotlin帮你封装了一个对象,这样可以保证不会出现空指针。数字类型也一样,所以在比较两个数字的时候,就有比较数据大小和比较两个对象是否相同的区别了。

在Kotlin中,三个等号===表示比较对象地址,两个==表示比较两个值大小。

由于不同的表示方式,较小类型并不是较大类型的子类型,较小的类型不能隐式转换为较大的类型。这意味着在不进行显式转换的情况下我们不能把Byte型值赋给一个Int变量。

valb:Byte=1//OK,字面值是静态检测的vali:Int=b//错误vali:Int=b.toInt()//OK位操作符对于Int和Long类型,还有一系列的位操作符可以使用,分别是:

shl(bits)–左移位(Java’s<<)shr(bits)–右移位(Java’s>>)ushr(bits)–无符号右移位(Java’s>>>)and(bits)–与or(bits)–或xor(bits)–异或inv()–反向字符的使用fundecimalDigitValue(c:Char):Int{if(c!in'0'..'9')throwIllegalArgumentException("Outofrange")returnc.toInt()-'0'.toInt()//显式转换为数字}数组数组的创建两种方式:一种是使用函数arrayOf();另外一种是使用工厂函数。如下所示,我们分别是两种方式创建了两个数组:

funmain(args:Array){//[1,2,3]vala=arrayOf(1,2,3)//[0,2,4]valb=Array(3,{i->(i*2)})//读取数组内容println(a[0])//输出结果:1println(b[1])//输出结果:2}字符串Kotlin支持使用三个引号"""来表示多行字符串,比如:

funmain(args:Array){valtext="""多行字符串多行字符串"""println(text)//输出有一些前置空格}String可以通过trimMargin()方法来删除多余的空白。

funmain(args:Array){valtext="""|多行字符串|编程狮|多行字符串|W3cschool""".trimMargin()println(text)//前置空格删除了}默认|用作边界前缀,但你可以选择其他字符并作为参数传入,比如trimMargin(">")。

valc=if(condition)aelsebwhen条件表达式when表达式类似java的switch语句。具体用法可以参考如下几个示例。

when(x){1,2->print("x==1")3->print("x==2")else->{//这里可以写成代码块print("x不是123")}}//使用in操作when(x){in1..10->print("xisintherange")invalidNumbers->print("xisvalid")!in10..20->print("xisoutsidetherange")else->print("noneoftheabove")}//使用is操作funhasPrefix(x:Any)=when(x){isString->x.startsWith("prefix")else->false}//可以用来取代ifelse链when{x.isOdd()->print("xisodd")x.isEven()->print("xiseven")else->print("xisfunny")}//in操作funmain(args:Array){valitems=setOf("apple","banana","kiwi")when{"orange"initems->println("juicy")"apple"initems->println("appleisfinetoo")}}kotlin循环控制For循环for(item:Intinints){//……}for(iinarray.indices){print(array[i])}//使用库函数withIndexfor((index,value)inarray.withIndex()){println("theelementat$indexis$value")}Break和Continue标签的使用//这块看的不是很懂,先做记录

在Kotlin中任何表达式都可以用标签(label)来标记。标签的格式为标识符后跟@符号,例如:abc@、fooBar@都是有效的标签。要为一个表达式加标签,我们只要在其前加标签即可。

loop@for(iin1..100){//……}现在,我们可以用标签限制break或者continue:loop@for(iin1..100){for(jin1..100){if(……)break@loop}}标签限制的break跳转到刚好位于该标签指定的循环后面的执行点。continue继续标签指定的循环的下一次迭代。

标签处返回Kotlin有函数字面量、局部函数和对象表达式。因此Kotlin的函数可以被嵌套。标签限制的return允许我们从外层函数返回。最重要的一个用途就是从lambda表达式中返回。回想一下我们这么写的时候:

funfoo(){ints.forEach{if(it==0)returnprint(it)}}这个return表达式从最直接包围它的函数即foo中返回。(注意,这种非局部的返回只支持传给内联函数的lambda表达式。)如果我们需要从lambda表达式中返回,我们必须给它加标签并用以限制return。

funfoo(){ints.forEachlit@{if(it==0)return@litprint(it)}}现在,它只会从lambda表达式中返回。通常情况下使用隐式标签更方便。该标签与接受该lambda的函数同名。

funfoo(){ints.forEach{if(it==0)return@forEachprint(it)}}或者,我们用一个匿名函数替代lambda表达式。匿名函数内部的return语句将从该匿名函数自身返回

funfoo(){ints.forEach(fun(value:Int){if(value==0)returnprint(value)})}当要返一个回值的时候,解析器优先选用标签限制的return,即return@a1意为"从标签@a返回1",而不是"返回一个标签标注的表达式(@a1)"。

Koltin中的类可以有一个主构造器,以及一个或多个次构造器,主构造器是类头部的一部分,位于类名称之后:

注意:无需对抽象类或抽象成员标注open注解。

openclassBase{openfunf(){}}abstractclassDerived:Base(){overrideabstractfunf()}嵌套类我们可以把类嵌套在其他类中,看以下实例:

classOuter{//外部类privatevalbar:Int=1classNested{//嵌套类funfoo()=2}}funmain(args:Array){valdemo=Outer.Nested().foo()//调用格式:外部类.嵌套类.嵌套类方法/属性println(demo)//==2}内部类内部类使用inner关键字来表示。

内部类会带有一个对外部类的对象的引用,所以内部类可以访问外部类成员属性和成员函数。

使用对象表达式来创建匿名内部类:

classTest{varv="成员属性"funsetInterFace(test:TestInterFace){test.test()}}/***定义接口*/interfaceTestInterFace{funtest()}funmain(args:Array){vartest=Test()/***采用对象表达式来创建接口对象,即匿名内部类的实例。*/test.setInterFace(object:TestInterFace{overridefuntest(){println("对象表达式创建匿名内部类的实例")}})}类的修饰符类的修饰符包括classModifier和accessModifier:

classModifier:类属性修饰符,标示类本身特性。abstract//抽象类final//类不可继承,默认属性enum//枚举类open//类可继承,类默认是final的annotation//注解类accessModifier:访问权限修饰符private//仅在同一个文件中可见protected//同一个文件中或子类可见public//所有调用的地方都可见internal//同一个模块中可见实例

classExample//从Any隐式继承注意:Any不是java.lang.Object。

如果一个类要被继承,可以使用open关键字进行修饰。

openclassBase(p:Int)//定义基类classDerived(p:Int):Base(p)构造函数:子类有主构造函数:如果子类有主构造函数,则基类必须在主构造函数中立即初始化。

openclassPerson(varname:String,varage:Int){//基类}classStudent(name:String,age:Int,varno:String,varscore:Int):Person(name,age){}//测试funmain(args:Array){vals=Student("W3cschool",18,"S12346",89)println("学生名:${s.name}")println("年龄:${s.age}")println("学生号:${s.no}")println("成绩:${s.score}")}子类没有主构造函数:如果子类没有主构造函数,则必须在每一个二级构造函数中用super关键字初始化基类,或者在代理另一个构造函数。初始化基类时,可以调用基类的不同构造方法。

classStudent:Person{constructor(ctx:Context):super(ctx){}constructor(ctx:Context,attrs:AttributeSet):super(ctx,attrs){}}DEMO:

/**用户基类**/openclassPerson{openfunstudy(){//允许子类重写println("我毕业了")}}/**子类继承Person类**/classStudent:Person(){overridefunstudy(){//重写方法println("我在读大学")}}funmain(args:Array){vals=Student()s.study();}如果有多个相同的方法(继承或者实现自其他类,如A、B类),则必须要重写该方法,使用super范型去选择性地调用父类的实现。

interfaceFoo{valcount:Int}classBar1(overridevalcount:Int):FooclassBar2:Foo{overridevarcount:Int=0}kotlin接口Kotlin接口与Java8类似,使用interface关键字定义接口,允许方法有默认实现,且可以实现多个接口。

interfaceMyInterface{funbar()//未实现funfoo(){//已实现//可选的方法体println("foo")}}classChild:MyInterface{overridefunbar(){//方法体}}接口中的属性接口中的属性只能是抽象的,不允许初始化值,接口不会保存属性值,实现接口时,必须重写属性:

interfaceMyInterface{varname:String//name属性,抽象的funbar()funfoo(){//可选的方法体println("foo")}}classChild:MyInterface{overridevarname:String="w3cschool"//重写属性overridefunbar(){//方法体println("bar")}}funmain(args:Array){valc=Child()c.foo();c.bar();println(c.name)}函数重写实现多个接口时,可能会遇到同一方法继承多个实现的问题。直接看demo就可以。

interfaceA{funfoo(){print("A")}//已实现funbar()//未实现,没有方法体,是抽象的}interfaceB{funfoo(){print("B")}//已实现funbar(){print("bar")}//已实现}classC:A{overridefunbar(){print("bar")}//重写}classD:A,B{overridefunfoo(){super.foo()super.foo()}overridefunbar(){super.bar()}}funmain(args:Array){vald=D()d.foo();d.bar();}kotlin扩展Kotlin可以对一个类的属性和方法进行扩展,且不需要继承或使用Decorator模式。

扩展是一种静态行为,对被扩展的类代码本身不会造成任何影响。

扩展函数扩展函数可以在已有类中添加新的方法,不会对原类做修改,扩展函数定义形式:

funreceiverType.functionName(params){body}receiverType:表示函数的接收者,也就是函数扩展的对象functionName:扩展函数的名称params:扩展函数的参数,可以为NULL以下实例扩展User类:

classUser(varname:String)/**扩展函数**/funUser.Print(){print("用户名$name")}funmain(arg:Array){varuser=User("W3cschool")user.Print()}实例执行输出结果为:用户名W3cschool下面代码为MutableList添加一个swap函数:

//扩展函数swap,调换不同位置的值funMutableList.swap(index1:Int,index2:Int){valtmp=this[index1]//this对应该列表this[index1]=this[index2]this[index2]=tmp}funmain(args:Array){vall=mutableListOf(1,2,3)//位置0和2的值做了互换l.swap(0,2)//'swap()'函数内的'this'将指向'l'的值println(l.toString())}实例执行输出结果为:[3,2,1]this关键字指代接收者对象(receiverobject)(也就是调用扩展函数时,在点号之前指定的对象实例)。

Kotlin可以创建一个只包含数据的类,关键字为data:dataclassUser(valname:String,valage:Int)

dataclassUser(valname:String,valage:Int)

funmain(args:Array){valjack=User(name="Jack",age=1)valolderJack=jack.copy(age=2)println(jack)println(olderJack)

}输出结果为:

User(name=Jack,age=1)User(name=Jack,age=2)

创建类的实例时我们需要指定类型参数:valbox:Box=Box(1)//或者valbox=Box(1)//编译器会进行类型推断,1类型Int,所以编译器知道我们说的是Box。以下实例向泛型类Box传入整型数据和字符串:

枚举类最基本的用法是实现一个类型安全的枚举。

枚举常量用逗号分隔,每个枚举常量都是一个对象。

enumclassColor{RED,BLACK,BLUE,GREEN,WHITE}枚举初始化每一个枚举都是枚举类的实例,它们可以被初始化:

classMyClass{companionobjectFactory{funcreate():MyClass=MyClass()}}该伴生对象的成员可通过只使用类名作为限定符来调用:

valinstance=MyClass.create()可以省略伴生对象的名称,在这种情况下将使用名称Companion:

classMyClass{companionobject{}}valx=MyClass.Companion其自身所用的类的名称(不是另一个名称的限定符)可用作对该类的伴生对象(无论是否具名)的引用:

classMyClass1{companionobjectNamed{}}valx=MyClass1classMyClass2{companionobject{}}valy=MyClass2请注意,即使伴生对象的成员看起来像其他语言的静态成员,在运行时他们仍然是真实对象的实例成员,而且,例如还可以实现接口:

companionobject{@JvmStaticfuntypeOf(type:String):NodeType{returnvalues().firstOrNull{it.type==type}}}Kotlin函数let函数首先let()的定义是这样的,默认当前这个对象作为闭包的it参数,返回值是函数里面最后一行,或者指定return

funT.let(f:(T)->R):R=f(this)简单示例:

funtestLet():Int{//funT.let(f:(T)->R):R{f(this)}"testLet".let{println(it)println(it)println(it)return1}}//运行结果//testLet//testLet//testLetapply函数apply函数是这样的,调用某对象的apply函数,在函数范围内,可以任意调用该对象的任意方法,并返回该对象

funT.apply(f:T.()->Unit):T{f();returnthis}代码示例:

funtestApply(){//funT.apply(f:T.()->Unit):T{f();returnthis}ArrayList().apply{add("testApply")add("testApply")add("testApply")println("this="+this)}.let{println(it)}}//运行结果//this=[testApply,testApply,testApply]//[testApply,testApply,testApply]with函数with函数是一个单独的函数,并不是Kotlin中的extension,所以调用方式有点不一样,返回是最后一行,然后可以直接调用对象的方法,感觉像是let和apply的结合。

funwith(receiver:T,f:T.()->R):R=receiver.f()代码示例:

funtestWith(){//funwith(receiver:T,f:T.()->R):R=receiver.f()with(ArrayList()){add("testWith")add("testWith")add("testWith")println("this="+this)}.let{println(it)}}//运行结果//this=[testWith,testWith,testWith]//kotlin.Unit

THE END
1.在下面的语句中()正确声明并初始化FLOAT的变量AFLOATF;BF=12;C...下面是四条顺序出现的声明语句,非法的初始化语句是() 免费查看参考答案及解析 float类型成员变量的默认初始化值是() 0.0F 免费查看参考答案及解析 下面4个变量声明语句中,正确的是()。 A、var default B、var my_house C、var my dog D、Var 2cats ...https://m.12tiku.com/newtiku/919848/36094131.html
1.java中变量的默认初始值腾讯云开发者社区java中变量的默认初始值 参考链接: Java中的变量 对于类的成员变量 不管程序有没有显示的初始化,Java虚拟机都会先自动给它初始化为默认值。 1、整数类型(byte、short、int、long)的基本类型变量的默认值为0。 2、单精度浮点型(float)的基本类型变量的默认值为0.0f。https://cloud.tencent.com/developer/article/1756428
2....中类的基本数据类型字段(成员变量)的默认初始化值本文详细介绍了Java中基本数据类型如int、String、char等在数组中的默认值,包括0、null和特定字符。同时指出,对于类成员变量,Java会确保赋予默认值,但局部变量必须显式初始化。此外,引用类型的默认值为null。理解这些基础知识对于编写健壮的Java代码至关重要。 https://blog.csdn.net/weixin_46703995/article/details/124519245
3.go语言结构体的数组成员默认值是什么结构体数组默认初始化仅仅对其中部分的成员变量进行初始化,要求初始化的数据至少有一个,其他没有初始化的成员变量由系统完成初始化,为其提供缺省的初始化值。各种基本数据类型的成员变量初始化缺省值如表9-1所示。 数据类型 缺省初始化值 Int 0 Char ‘/0x0’ float 0.0 https://blog.51cto.com/u_16213702/9018578
4.聊聊java变量的初始化之后的默认值java变量初始化后的默认值 对于类的成员变量 不管程序有没有显示的初始化,Java 虚拟机都会先自动给它初始化为默认值。 1、整数类型(byte、short、int、long)的基本类型变量的默认值为0。 2、单精度浮点型(float)的基本类型变量的默认值为0.0f。 3、双精度浮点型(double)的基本类型变量的默认值为0.0d。 https://www.jb51.net/article/220540.htm
5.java什么是成员变量Java基础可以在声明成员变量的同时对其进行初始化,如果声明成员变量时没有对其初始化,则系统会使用默认值初始化成员变量。 初始化的默认值如下: 整数型(byte、short、int 和 long)的基本类型变量的默认值为 0。 单精度浮点型(float)的基本类型变量的默认值为 0.0f。 https://www.php.cn/java/base/440096.html
6.Java基础笔试题C、系统会对全局(成员)变量指定默认的值,也会对局部变量赋值。 D、局部变量在使用之前,必须对其进行显式初始化。 11、下面的各种数据类型的默认初始化值表示错误的一项是( )。 A、int是0 B、float 是0.0 C、char 是‘u0000’ D、boolean是false https://www.unjs.com/fanwenwang/ziliao/157487.html
7.笔试题(面向对象)C、系统会对全局(成员)变量指定默认的值,也会对局部变量赋值。 D、局部变量在使用之前,必须对其进行显式初始化。 11. 下面的各种数据类型的默认初始化值表示错误的一项是( )。 A、int是0 B、float 是0.0 C、char 是‘u0000’ D、boolean是false https://www.yjbys.com/bishi/timu/366683.html
8.初始值设定项MicrosoftLearninti1;floatf;charc; 如果定义数组时不使用初始化表达式,则进行默认初始化。 数组进行默认初始化时,其成员将进行默认初始化并具有不确定的值,如以下示例所示: C++ intint_arr[3]; 如果数组成员没有默认构造函数,则编译器将发出错误。 常量变量的默认初始化 ...https://learn.microsoft.com/zh-cn/cpp/cpp/initializers
9.C++中结构体的类型定义和初始化以及变量引用但是由于C++提供了类(class )类型,一般情况下,不必使用带函数的结构体,因此在本章中只介绍只含数据成员的结构体,有关包含函数成员的结构体将在后续章节进行介绍。 结构体类型变量的定义方法及其初始化 以上只是指定了一种结构体类型,它相当于一个模型,但其中并无具体数据,系统也不为之分配实际的内存单元为了能在程...https://www.xiuzhanwang.com/a1/Cyuyan/2726.html
10.四川工商学院创新创业示范课程。【解析】不能将double类型的常量赋值给float类型的变量。 9.在编写Java程序时,如果不为类的成员变量定义初始值,Java会给出它们的默认值,下列说法中不正确的一个是( D )。 (A)byte的默认值是0 (B)boolean的默认值是false (C)char类型的默认值是’\0’ (D)long类型的默认值是0.0L 10.下列语句中...https://jsjxy.stbu.edu.cn/sfkc/xitiziliao.html
11.C语言中基本的数据类型有哪些开发技术}stu = {"Chenhao",21,"男"};structstudentstu1 = stu;//不是通过指针指向来赋值,确确实实是复制了一份相同的stu成员变量给放到了新变量stu1的存储空间里,也就是stu1如实地开辟了自己的空间 AI代码助手复制代码 以上赋值的方式需要注意初始化值的类型和顺序要与结构体声明时成员对应的类型和顺序保持一致!另外...https://www.yisu.com/zixun/321738.html