**V E _**:)
我只是搬运工,对搬运工不能有太高的要求。 -_-!
Hello Kotlin
-
IDE我选择的是idea (不要问我为什么)
-
新建工程选择Kotlin就可以了
新建向导
-
创建完成的目录结构
工程结构 -
新建一个Kotlin文件(文件名不用跟 .kt)
-
Hello Kotlin代码
fun main(args: Array<String>) {
println("Hello Kotlin.")
}
-
点击左侧的Kotlin图标运行
-
Hello Kotlin就算是走完了~~ 这里还有一些东西要提出来
-
println这个究竟是个什么函数(Ctrl + 鼠标左键)
println源码
-
println这个究竟是个什么函数(Ctrl + 鼠标左键)
$%%%%%%%%%%%%%%%%%%%%%%%%%%%
下面高能预警~~ 各种官网语法例子在路上
======================> 传送门
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%
入门
1.包名
- 这里的包名可以不用和文件的路径对应(包名可以随意而不用管这个源文件的路径)
- Kotlin里面的包名(这个和java的语法一样)
package my.demo
import java.util.*
- 这里修改上面的Hello Kotlin代码(加入包名的定义 )
package com.suse.dapi
fun main(args: Array<String>) {
println("Hello Kotlin.")
}
-
我们去看看 out文件夹(可以看到编译之后的class文件其实是和文件夹对应起来了的)
-
我们修改刚才那个文件的包名再试试
修改包名
编译之后class的路径
- 默认导入的包
kotlin.*
kotlin.annotation.*
kotlin.collections.*
kotlin.comparisons.* (since 1.1)
kotlin.io.*
kotlin.ranges.*
kotlin.sequences.*
kotlin.text.*
java.lang.*
kotlin.jvm.*
2.基本数据类型(这里需要注意哈~~ kotlin中所有的都是对象包括int之类的基本类型,so这里说的基本类型其实也是对象哈)
- Double类型 (64位)
- Float 类型(32位)
- Long类型(64位)
- Int(32位)
- Short类型(16位)
- Byte类型(8位)
package com.suse.dapi.demo
fun main(args: Array<String>) {
println("Hello Kotlin.")
val mDouble: Double = 12345.0
val mFloat: Float = 12323f
var mLong: Long = 123
var mInt: Int = 1232
var mInt2 = 123213 //省略了变量类型
mDouble = 123.0 //尝试修改 val 申明的变量
mLong = 12323
mInt = mDouble.toInt() // double ==> int
mLong = mInt.toLong() // int ==> long
}
-
这里引入了变量的定义
- 变量使用var 或者 val来申明(区别是val是只读变量,var是可变变量)
- 变量使用:来申明类型,类型申明也可以省略~ 这就由系统来推断是什么类型
- 变量还有好些需要注意的地方后面遇到了在提哈
-
这里还有一个类型转换的方法(每个类型都有,只要是Number类的子类都可以使用,上面提到的基本类型都是Number的子类哈)
Number源码 -
字符(字符不能直接和数据比较,但是Char也有 toInt之类的方法)
var mChar: Char = 'P'
mChar == 1 // 错误
mChar == 'a'
mChar.toByte()
mChar.toInt()
- 虽然字符也有toInt方法,但是字符并不是Number的子类哈
Char的部分源码
-
Boolean 布尔类型 ,这个的值有两个 true false
-
数组类型 Array(系统库提供了一个arrayOf的方法可以创建 Array数组)
var intArray = arrayOf(1,2,3) //这里返回的实际上是Array对象
println(intArray[0])
var intArray: Array<Int> = arrayOf(1,2,3)
println(intArray[0])
arrayOf源码
-
系统还提供了一个函数 arrayListOf(实际上就是返回的java里面的ArrayList)
-
字符串类型String
var name: String = "dapi"
var number = "123345666"
- 字符串还有两个有趣的语法(和PHP的字符串类似 ,直接看例子吧)
var content = """
这里面可以写各种东西
var name = "" .....
这个就类似 html 里面的 <pre></pre>标签
$name ====> ${'$'} // 这个是在字符串里面输出 $
"""
var templ = "i am $name, my number is ${ name + number}" //字符串模板
- 模板里面的 ${} 或者 $变量名 这个就是一个表达式,${}里面还可以调用函数
3.流程控制
- 条件语句 if(if可以是一个表达式,也可以有返回值)
var number1 = 0x0033
var number2 = 0x0022
var flag: Boolean = false
// 一般的 if
if(number1 > number2){
flag = true
}else{
flag = false
}
// 有返回值的 if
flag = if (number1 > number2){
println(".....")
true // 吧返回值放到最后就可以了
}else{
println("-----")
false
}
// 表达式的 if
flag = if (number1 > number2) true else false
- 循环语句 for while do..while
- for
/**
*
* 以前的 for (int i = 0;i < 10;i++) 循环已经不行了
* for 专门用来迭代 有 iterator 方法的集合
*
*/
var numbers = arrayOf(1,2,3,4,5)
for (item in numbers){
//..
}
for (item in numbers.iterator()){
//..
}
/**
*
* 这里是的index 是下标 0 ,1 ,2, 3, 4,...
* 查看源码发现 indices 其实返回的就是一个数组 Array 实际上也是使用的 iterator
*
*/
for (index in numbers.indices){
// ..
}
/**
* 这里 (index,value) 其实就是下标 和 对应的值
* 查看源码发现 withIndex 其实返回的就是一个数组 Array 实际上也是使用的 iterator
*
*/
for((index,value) in numbers.withIndex()){
// ...
}
-
所以for循环就是专门用来迭代 iterator 的 ,只要 in 的右边返回的是一个包含iterator(): Iterator<T>方法的对象(或者是直接是一个Iterator对象)就可以了
-
while(偷哈懒 ~~)
while (x > 0) {
x--
}
do {
val y = retrieveData()
} while (y != null) // y is visible here!
- when语句(这个就和以前的 switch类似 , switch 和 if 的结合)
var number3 = 100
when(number3){
in 1..101 -> println("1")
in 10..102 -> println("2")
else -> println("3")
}
// 结果是 3
when{
number3 in 1..102 -> {
//...
}
number3 == 100 -> {
//...
}
else -> {
//...
}
}
- break 和 continue (这个就是多了一个标签的情况)
while(number3 < 200){
if(number3 % 2 == 0){
continue
}
if(number3 == 150){
break
}
number3++
}
//添加标签的情况
tagert@
while(number3 < 200){
while(number3 < 150){
break@tagert
}
number3++
}
类和对象(终于可以谈对象了~~)
- 最简单的类定义
/**
* 这样就定义了一个类了
*/
class MyArray{
}
- 稍微添加一点属性的类
class MyArray{
var items: Array<String> = arrayOf("name1","name2","name3")
var total = items.size
}
- 稍微再添加一点方法(仿照着Array这个类来吧 _,方法的语法后面再提)
class MyArray{
var items: Array<String> = arrayOf("name1","name2","name3")
var total = items.size
public operator fun iterator(): Iterator<String>{
return items.iterator()
}
}
- 不知道还记不记得 前面说的 for 循环可以遍历提供 iterator方法的对象
var myArray = MyArray()
for (item in myArray){
println(item)
} // 这样写是完全可以的哈
- 我们再来添加几个构造方法(Kotlin里面的构造方法分为两种,就类似 adc 和 辅助 下路两基友)
- 首先来看主构造方法怎么添加
class MyArray public constructor(names: Array<String>){
var items: Array<String> = arrayOf("name1","name2","name3")
var total = items.size
/**
* 主构造就是申明在 类的定义后面... 有点智障啊~~
* 主构造的参数是在 init 里面访问的~~ 也只有这里访问
* 这个init 方法就像静态代码块一样 放在前面的先执行 这个也是有点智障啊~~
*/
init {
items = names
}
public operator fun iterator(): Iterator<String>{
return items.iterator()
}
}
- 看了上面那个智障的代码 有没有想打人啊~~ (Kotlin提供了一个简单的写法,将属性 和 主构造写到一起去)
class MyArray public constructor(var items: Array<String>,var total: Int){
var orther: String = "tag" //这里一样可以写其他的属性
public operator fun iterator(): Iterator<String>{
return items.iterator()
}
}
-
辅助构造函数,这个就和C#很类似了(官方叫的是二级构造函数,也是一个智障)(不管怎么样~~ 主构造都感觉有点智障的感觉)
-
一般的辅助构造函数
class MyArray {
var items: Array<String> = arrayOf("name1","name2","name3")
var total = items.size
constructor(name: Array<String>){
items = name
}
public operator fun iterator(): Iterator<String>{
return items.iterator()
}
}
- 上面是没有主构造函数的时候的写法~(还算正常),当有了主构造函数之后就要 主动调用主构造函数
class MyArray constructor(size: Int){
var items: Array<String> = arrayOf("name1","name2","name3")
var total = items.size
init {
total = size
}
constructor(name: Array<String>,size_: Int) : this(size_){
items = name
}
public operator fun iterator(): Iterator<String>{
return items.iterator()
}
}
- 有了类就可以创建对象了(其实前面都已经用了 没有new 没有 new 没有 new)
var myArray = MyArray()
-
Kotlin中也有类似Java中Object的类Any,所有类的父类(什么鬼~~)
Any源码
-
最一般的继承(只有类前面有 open 修饰的类才能被继承)
open class MyArray {
var size: Int = 0
}
/**
* 继承的时候需要调用父类的构造方法 这里是默认的构造方法
*/
class MyArray2 : MyArray() {
}
- 父类没有默认构造方法的时候
open class MyArray constructor(size: Int){
var size: Int = 0
}
/**
* 继承的时候需要调用父类的构造方法
*/
class MyArray2 constructor(size: Int): MyArray(size) {
}
/**
*
* 这里是不会生成默认的构造方法的~~
*
*/
open class MyArray {
var size: Int = 0
constructor(size: Int){
}
}
/**
* 继承的时候需要调用父类的构造方法 这里就不能调用父类的无参数构造了
*/
class MyArray2 constructor(size: Int): MyArray(size) {
}
- 不在主构造函数里面初始化父类(使用super来初始化)
/**
*
* 这里是不会生成默认的构造方法的~~
*
*/
open class MyArray {
var size: Int = 0
constructor(size: Int){
}
}
/**
* 继承的时候需要调用父类的构造方法 使用 super
*/
class MyArray2 : MyArray{
constructor(size: Int) : super(size)
}
- 方法的复写(方法的讲解放到 后面再说)(能看到这里的 耐心都挺好啊~~ )
/**
*
* 这里是不会生成默认的构造方法的~~
*
*/
open class MyArray {
var size: Int = 0
constructor(size: Int){
}
open fun say(){
// ..
}
}
/**
* 继承的时候需要调用父类的构造方法 使用 super
*/
class MyArray2 : MyArray{
constructor(size: Int) : super(size)
override fun say(){
}
}
-
还有一个需要注意的是 如果父类 和 实现的接口中包含同一个方法 则必须重写
-
抽象类这个就和java一样了~~
/**
*
* 这里是不会生成默认的构造方法的~~
*
*/
open abstract class MyArray {
var size: Int = 0
constructor(size: Int){}
open fun say(){
// ..
}
abstract fun aSay()
}
/**
* 继承的时候需要调用父类的构造方法 使用 super
*/
class MyArray2 : MyArray{
override fun aSay() {
}
constructor(size: Int) : super(size)
override fun say(){}
}
- 类里面的属性 (get 和 set方法已经有了默认的实现了~~ 也比较简便)
class User{
var nickName: String = "dapi" //这里的属性必须有默认值
var name: String //这个不用设置默认值
get() = "dapi"
set(value){
name = value
}
var number: String = "122323232"
set(number) {
this.number = number
}
}
- 属性这里需要注意的地方就是 基本类型是必须有初始值的~~(如果不想设置初始值就要使用下面的方法)
class User{
var nickName: String = "dapi" //这里的属性必须有默认值
var name: String //这个不用设置默认值
get() = "dapi"
set(value){
name = value
}
var number: String = "122323232"
set(number) {
this.number = number
}
lateinit var items: Array<String>
lateinit var tag: String
}
- 接口(Kotlin中的接口和java8中的接口很类似,可以有方法实现)
interface Flyable{
fun fly()
fun 呵呵(){
}
}
class User : Flyable{
override fun fly() {
// do fly
}
var nickName: String = "dapi" //这里的属性必须有默认值
var name: String //这个不用设置默认值
get() = "dapi"
set(value){
name = value
}
var number: String = "122323232"
set(number) {
this.number = number
}
lateinit var items: Array<String>
lateinit var tag: String
}
-
可见性修饰符private ,protected,internal,public(默认)(这个和java类似的哈~~)
-
扩展(什么鬼
,感觉是个黑科技啊)
var arrs = arrayOf("xx")
arrs.test()
fun Array<String>.test(){
println("test")
}
- 数据类(这个感觉很有用~~)(就是 这些类仅仅就是用来存一些数据信息,里面不会有业务逻辑)
data class Person(var name: String,var number: String)
- sealed 修饰的类 (这种类的子类只能是和父类在同一个文件中~)
sealed class Expr
data class Const(val number: Double) : Expr()
data class Sum(val e1: Expr, val e2: Expr) : Expr()
object NotANumber : Expr()
fun eval(expr: Expr): Double = when (expr) {
is Const -> expr.number
is Sum -> eval(expr.e1) + eval(expr.e2)
NotANumber -> Double.NaN
}
关于类的东西还有一些没有提到~ 自己去看官网吧~ 我都还不熟
函数
- 最一般的函数(没有参数,没有返回值)
fun doSome(){
println("...")
}
-
函数的定义使用的是 fun 关键字
-
有参数的函数(有参数,没有返回值的函数)
fun doSome(message: String,other: String){
println("... $message ... $other")
}
- 有返回值得函数(有返回值,没有参数)
fun doSome(): Int{
println("...")
return 0
}
- Kotlin里面有一个类似void的关键字 Unit(默认可以不写),当一个函数返回值为空的时候可以使用
fun doSome(): Unit{
println("...")
}
- 有返回值和参数的函数
fun doSome(message: String,name: String): Int{
println("...")
return 0
}
- 表达式函数(说表达式其实也不准确~~ 就说没有大括号的函数~)
fun doSome() = println("xxx") //可以没有返回值哈 等号右边是函数体
fun doSome(): String = "dapi" // 这个也可以有返回值
Lambda表达式
- 这个表达式有两部分构成,一个是参数列表 一个是返回值
- 首先来看怎么定义
/**
*
* () 里面的就是参数列表 -> 右边的就是返回值类型
*
*/
var sum: (Int,Int) -> Int // 定义一个求和的 表达式
var max: (Int,Int) -> Int // 定义一个求最大值得表达式
- 在定义的时候赋初值
/**
*
* () 里面的就是参数列表 -> 右边的就是返回值类型
*
*/
var sum: (Int,Int) -> Int = {number1,number2 -> number1 + number2}
var max: (Int,Int) -> Int = {x,y -> if (x > y) x else y}
- 这个表达式也可以做函数的参数
fun doSome(message: String,transform: (String) -> String): String{
return transform(message)
}
doSome("dapi",{messag -> messag.toUpperCase()}) // DAPI
- 如果只有一个参数可以用it代替这个参数
fun doSome(message: String,transform: (String) -> String): String{
return transform(message)
}
doSome("dapi",{it.toUpperCase()}) // DAPI
Nothing is certain in this life. The only thing i know for sure is that. I love you and my life. That is the only thing i know. have a good day
网友评论