前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >介绍Kotlin第一部分(翻译篇)

介绍Kotlin第一部分(翻译篇)

作者头像
code_horse
发布2018-07-02 11:24:42
6240
发布2018-07-02 11:24:42
举报
文章被收录于专栏:Android NoteAndroid Note
1、介绍Kotlin

Kotlin是jvm新的开发语言。 谷歌推广Kotlin作为其基于java的Android平台上的第一类语言在五月份。从那之后我就纳闷:这是什么语言?Kotlin已经有好几年了,并且在2016年2月正式在生产系统上运行,语言后的1.0版本,为期一年左右。该语言已经获得很多的赞赏和喜爱。 在这篇文章中我们将涵盖语法等基本构建块,在介绍Kotlin第二部分,我们将接触变量,函数,类,接口和对象。最后,在第三部分,我们来看一看控制流程的几个例子。

1、构建过程

当Kotlin在发展的时候,您的构建过程或多或少和旧的java程序类似。既然您已经熟悉了这些,就没有必要学习新的东西,Gradle/Maven插件:引入Kotlin的构建过程和构建工具。 您可以通过添加Kotlin插件在您的Gradle/Maven中构建脚本。如何做到这一点以及了解更多信息,可以从官方文档Kotlin中找到关于 Maven /Gradle的更多介绍。

2、Kotlin语法

一位伟人曾经说过 talk is cheap, show me the code。 貌似在接触新语言时第一句学到的总是以Hello World开始的。那我们就从这里开始吧。

代码语言:javascript
复制
print("Hello World")

现在,我们已经看到了不同于java的地方。有一些我们熟悉的东西()表示函数调用,但没有分号去结尾,不过看起来也很整齐。好了,下面让我们开始去了解Kotlin吧。

① Kotlin变量

在Kotlin中声明变量有一些不同,我们有关键字valvar,这看起来很相似,但其实有一个重要的区别:

当变量被声明为val时是不可变的(只读),你只能给它分配一次值。变量被声明为var是可变的,可以给它重新分配。

代码语言:javascript
复制
val hello: String = "hello"
val world: String
world = "world"
 
var helloWorld: String = "Hello"
helloWorld = "Hello World"

注意,变量类型如何定义?用冒号分隔。这背后还有一个理由,编译器现在可以决定是否要进行类型推断。这意味着Kotlin比Java有着更强大的类型推断。实际上,你也可以不用声明这些类型编译器也会明白你的意思。

代码语言:javascript
复制
val hell0 = "hi"
val w0rld = "earth"

只有当变量被赋值的时候,该变量的类型才能被推断出来。

② fun

这是什么样的功能呢?由于我们用fun来声明它们,它一定很有趣!哈哈。?

代码语言:javascript
复制
// 无返回值. (也可以这么写 --> fun sayIt (a: String): Unit)
fun sayIt (a: String) { 
    println(a)
}
 
// 有返回值
fun returnIt (returnable: String): String {
    return returnable
}
 
//作为具有推断返回类型和自动返回的单表达式函数
fun returnIt2 (turntable: String) =
    turntable

类型声明遵循相同的模式在这里-它排在后面。在我们的第一个我们不返回任何东西,所以我们可以省略到类型,在这种情况下可以使用Unit。在第二个函数中,我们定义必须返回一个String,使用return语句。最后一个比较令人费解,没有大括号,只是一个等号。这意味着fun是一个表达式,它可以自动返回。

正如你所看到的,在表达式的返回类型上是可选的。可以省略或者留在原位,什么让你更方便(经验法则:长的表达式,把它放在后面。短的表达式,它可以省略)。 Kotlin还引入了可选的命名函数参数的概念。这是很有用的,特别是如果你的函数成长为很多同类型和多种不同参数的时候。

代码语言:javascript
复制
fun optFun(isItFun: Boolean = true, whyIsItFun: String = "Because") = if (isItFun) whyIsItFun else "It's not fun"
 
println(optFun()) // Because
println(optFun(false)) // It’s not fun
println(optFun(whyIsItFun = "It's Summer!")) // It's Summer!

在这个代码块中,我们使用默认值来定义我们的函数参数。当我们这么写的时候,我们可以直接调用该函数的0个、1个或者多个它的参数。

③ 类,接口和对象

与Java一样,Kotlin也具有类和接口。Kotlin团队决定让代码组织更加愉快和语言更加简洁。让我们先了解一下类。

A、类
代码语言:javascript
复制
class SimpleClass
 
// 或者 --> class constructor SimpleClassWithConstructor(val chop: String)
class SimpleClassWithConstructor(val chop: String)

在Kotlin中有很多方式可以创建类。在上面的代码块中给了我们提示:

  • 命名约定以大写字母开头
  • 没有花括号
  • 还有就是在这个例子中没有可见性修改
  • 我们仍然使用class关键字 第二个例子是相似的,但它有一个构造函数。构造函数绑定类的属性(在大多数情况下可以不用关键字constructor,只需要添加类的注解或类的可见性),另一种方式,使得Kotlin更加简洁,当我们实例化这个类时需要给chop赋值。
代码语言:javascript
复制
val lamb = SimpleClassWithConstructor("Hello")

在Kotlin中属性默认是公有的,所以访问该属性的最简单方法:

代码语言:javascript
复制
println(lamb.chop)

这个类不具有任何功能,它只是为我们的数据提供容器。我们可以自定义在里面添加fun类功能。在这种情况下,我们需要使用花括号来包裹我们的声明:

代码语言:javascript
复制
class SimpleClassWithConstructor(val chop: String) {
    fun sayItMate(): String = chop + ", mate"
}

我们可以在这里添加附加的属性,其它类,额外的构造函数或初始化块,我们可以给这些单独分配可见性。

init在Kotlin中做的事情,就是我们通常在Java构造函数中做的事情。如果你想在类中创建一个类,你可以使用inner关键字标记它,以便访问外层类的成员。

代码语言:javascript
复制
class Kenny(val celly: String) {
    lateinit var wheel: CanadianPerson
    val friend: String
 
    init {
        friend = "buddy"
    }
    
    fun initializeWheel (wheeler: String) {
        wheel = CanadianPerson(wheeler)
    }
    
    inner class CanadianPerson(val snipe: String)
 
    // 美元符号使用字符串插值,并使用该属性中定义的toString实现替换$ -prefixed属性名称
    fun sayItCanadianWay(): String = "${wheel.snipe} $celly, $friend"
}
 
val d = Kenny("friend")
d.initializeWheel("I’m not")
print(d.sayItCanadianWay()) // I'm not your friend, buddy

我们通过使用lateinit关键字来告诉编译器,这个属性不为空,即使我们不立即初始化它,这对于不在构造函数中初始化属性很有用。注意,我们的lateinit属性必须是可变的。

init相当于Java中的构造函数块,在那里,我们实例化类时,我们可以执行所需的动作。在这种情况下,我们将一个String赋值给我们的属性。

接下来,我们有一个函数,最终赋值给我们的lateinit属性,实例化一个内部类CanadianPerson,这个内部类只是我们数据的载体。

最后,我们将调用一个函数,这个函数将返回一个String,它使用字符串插值将它们解析并展示出来。

当向类添加其他构造函数时,我们需要调用它们原始的构造函数。

代码语言:javascript
复制
class DoubleTrouble(val str: String){
    constructor(lamb: SimpleClassWithConstructor): this(lamb.chop)
}

我们在类中添加一些简单的功能,除了保存数据什么都不做。

对于这些类型的数据传输对象。Kotlin引入了一个关键字来定义它们:data class。它不同于标准的类,一个data class自动生成equals,hashcode,toString和copy功能。前三个对Java开发者来说是比较熟悉的,第四个是个很好的补充,可以帮助我们从只读数据类创建类似的对象。该copy功能可以这么用:

代码语言:javascript
复制
data class DataClass(val str: String, val num: Int)
val daata = DataClass("Hello", 3)
val peeta = daata.copy(str = "Goodbye")

在这种情况下,我们的peeta包含了num=3和str=“Goodbye”。

我们也可以去获取component数据类对象,这些组件函数通过解构来访问数据类中数据的一种方式。这有利于通过简单的一行调用来获取数据类中的单个属性。

代码语言:javascript
复制
val (str, num) = peeta

有了这个技巧,我们的变量str和num的值分别为"Goodbye"和3。请注意,解构变量的顺序取决于数据类中属性的顺序;这些名字根本不重要。

另外还有两个顶级结构interface和objects。

b、接口

Kotlin中接口与Java中没有什么不同,

代码语言:javascript
复制
interface Sayer {
    val value: String
    fun sayIt(): String
}
 
class SayerClass: Sayer{
    override val value: String = "Hello"
    override fun sayIt(): String = "$value, world"
}
 
println(SayerClass().sayIt()) // Hello, world

如您所见,这与Java非常相似,像Java8一样,Kotlin也可以在接口中提供默认实现,我们可以利用这个特性实现上面一样的效果。

代码语言:javascript
复制
interface Sayer {
    val value: String
    fun sayIt(): String {
        return "$value, world"
    }
}

使用这个我们不必重新实现类中的函数。请注意,override关键字在Kotlin中是强制性的。

c、对象
代码语言:javascript
复制
object SingletonClass{
    fun sayIt(): String = "Hello world"
}
 
class CompaniedClass(val str: String){
    companion object Printer{
        fun sayIt(): String = "Hello world"
    }
}

这是什么呢?你可以使用object关键字创建SingletonClass的单例。

代码语言:javascript
复制
SingletonClass.sayIt() // Hello world

Companied对象是略有不同的,它在一个类中定义,它仍然是一个单例,它可以使用包装类的名称来访问。

代码语言:javascript
复制
CompaniedClass.sayIt() // Hello world
4、控制流程(if,when,for)
a、if

if在Kotlin中的语句或多或少与Java类似,下面我们来看一下它们的不同:

代码语言:javascript
复制
val three = 4
if (three != 3) {
    println("Liar!")
} else{
    println("Good job")
}

这看起来与Java完全相同。但是也略有不同。

代码语言:javascript
复制
val three = 4
val goodOrNot = if(three != 3) {
    "Liar!"
} else{
    "Good job"
}
println(goodOrNot) // Liar!

如果Kotlin语句实际上是表达式,它返回它们块中的最后一个值,

b、when

我们常用的switch-case三元运算符有着同样的命运,它已被Kotlin的when所取代。

代码语言:javascript
复制
when (three) {
    3 -> print("three is three")
    2 -> print("three is two?!?")
    else -> print("I don't know what's going on anymore")
}

正如你所看到的,else替代了default->替换了:字符,关键字break也不再需要,因为when表达式将在第一个为真时停止。这些when表达式有一些有趣的地方,它们可以使用任何类型的表达式进行判断,许多情况下,可以捆绑在一起,而对于数值,可以判断它们的范围。

代码语言:javascript
复制
when (three) {
    3 -> print("three is three")
    1,2 -> print("three is two or one?!?")
    in 4..10 -> print("What? Three can't be between 4 and 10!")
    else -> print("I don't know what's going on anymore")
}

同样的,我们也可以使用when来返回具体值。虽然这看起来有点像if表达式。

代码语言:javascript
复制
val three = 4
val goodOrNot = when {
    three != 3 -> "Liar!"
    else -> "Good job"
}
println(goodOrNot) // Liar!
c、for

for循环相对于Java有挺大的改动。

代码语言:javascript
复制
for (i in 1..10) {
    print(i)
} // 12345678910
 
for (i in 1..10 step 2) {
    print(i)
} // 13579
 
val lst = listOf(1,2,3)
for (i in lst){
    print(i)
} // 123

在第一个例子中我们使用in关键从range中通过..来分配i的值。第二个例子中使用step关键字,表示我们要从这个范围中取其它值。第三个例子循环列表,将listof值打印出来。

总结

以上就是Kotlin语言的基本组成部分,有了这些你就可以使用Kotlin了。希望在看完这篇文章后,你对Kotlin会有自己的看法,在下一章中我们将介绍null safety, lambdas, collections, and types以及Kotlin语言中几个便利的功能

快乐工作,享受编程!
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017.09.12 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、介绍Kotlin
  • 1、构建过程
  • 2、Kotlin语法
    • ① Kotlin变量
      • ② fun
        • ③ 类,接口和对象
          • A、类
        • b、接口
          • c、对象
          • 4、控制流程(if,when,for)
            • a、if
              • b、when
                • c、for
                • 总结
                  • 快乐工作,享受编程!
                  相关产品与服务
                  容器服务
                  腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档