kotlin

概述

服务端

Kotlin 非常适合开发服务器端应用程序,可以让你编写简明且表现力强的代码, 同时保持与现有基于 Java 的技术栈的完全兼容性以及平滑的学习曲线:

  • 表现力:Kotlin 的革新式语言功能,例如支持类型安全的构建器委托属性,有助于构建强大而易于使用的抽象。
  • 可伸缩性:Kotlin 对协程的支持有助于构建服务器端应用程序, 伸缩到适度的硬件要求以应对大量的客户端。
  • 互操作性:Kotlin 与所有基于 Java 的框架完全兼容,可以让你保持熟悉的技术栈,同时获得更现代化语言的优势。
  • 迁移:Kotlin 支持大型代码库从 Java 到 Kotlin 逐步迁移。你可以开始用 Kotlin 编写新代码,同时系统中较旧部分继续用 Java。
  • 工具:除了很棒的 IDE 支持之外,Kotlin 还为 IntelliJ IDEA Ultimate 的插件提供了框架特定的工具(例如 Spring)。
  • 学习曲线:对于 Java 开发人员,Kotlin 入门很容易。

android

  • 代码更少、可读性更强。花更少的时间来编写代码与理解他人的代码。
  • 成熟的语言与环境。自 2011 年创建以来,Kotlin 不仅通过语言而且通过强大的工具在整个生态系统中不断发展。 现在,它已无缝集成到 Android Studio 中, 并被许多公司积极用于开发 Android 应用程序。
  • Android Jetpack 与其他库中的 Kotlin 支持KTX 扩展 为现有的 Android 库添加了 Kotlin 语言特性,如协程、扩展函数、lambdas 与命名参数。
  • 与 Java 的互操作性。可以在应用程序中将 Kotlin 与 Java 编程语言一起使用, 而无需将所有代码迁移到 Kotlin。
  • 支持多平台开发。不仅可以使用 Kotlin 开发 Android,还可以开发 iOS、后端与 Web 应用程序。 享受在平台之间共享公共代码的好处。
  • 代码安全。更少的代码与更好的可读性导致更少的错误。Kotlin 编译器检测这些剩余的错误,从而使代码安全。
  • 易学易用。Kotlin 非常易于学习,尤其是对于 Java 开发人员而言。
  • 大社区。Kotlin 得到了社区的大力支持与许多贡献,该社区在全世界范围内都在增长。 根据 Google 的说法,Play 商店前 1000 个应用中有 60% 以上使用 Kotlin。

还可以用于js,原生开发,数据科学开发

Kotlin in Jupyter notebook

基础

基本语法


  • package my.demo

  • 程序入口 ——没有类

    fun main(){
      println("hello world")
    }
  • 函数

    fun sum(a:Int, b:Int):Int{
        return a+b
    }

![image-20200920172903322](/Users/chensong/Library/Application Support/typora-user-images/image-20200920172903322.png)

  • 无返回值函数

    fun printSum(a:Int,b:Int):Uint{
      println("$a + $b = ${a + b}")
    }

    printSum(1, 2)打印结果->1+2=3

  • 变量

    //variable readonly 变量赋值 
    val a:Int = 1 
    val b = 2 //自动推断
    val c : Int //没有初始值,必须要类型
    
    //可赋值变量
    var x = 1
  • 条件表达式

    if 语句

    fun minNumber(a:Int,b:Int):Int{
      if (a > b){
        return b
      }
      else{
        return a
      }
    }
    
    //表达式写法
    fun minNumber(a:Int,b:Int)=if (a > b) a else b  
  • 空值检测

    如果某个变量可以为空,必须在声明后面显示加上 ?

    也就是说,kotlin 默认变量为非空

    fun printInt(a:String) Int?{
    
    }

    举例:

    var littlesong: String="little"
    littlesong=null//会报错
    var littlesong: String? ="little"
    littlesong=null//不会报错
  • for循环

    类似java中的foreach

    val items = listOf("one","two","three")
    for (item in items){
      println(item)
    }

    还支持区间,类似python

    for (i in 1..10){
      println(i)
    }
  • while循环

    与java几乎没有区别k

  • when表达式

    fun swichString(s:String){
      when(s){
      "one" -> println("s = 1")
      "two" -> println("s = 2")
       else -> {
        println("s = all")
       }
      }
    }
    swichString("one")
    

基本类型

  • 浮点数:

    小数类型默认Double,如果要用float,显示使用f后缀

    val pi = 3.14 //Double
    val eFloat = 1.2345f //Float

    不支持隐式转换,只能显示转换,方法如下:

    • toByte(): Byte
    • toShort(): Short
    • toInt(): Int
    • toLong(): Long
    • toFloat(): Float
    • toDouble(): Double
    • toChar(): Char
    val i: Int = b.toInt
  • 数字装箱:

    以127为界限,如果超过127,将被kotlin转换为对象,两个对象指向同一个数字将不相等

    val a: Int = 127
    val boxedA: Int? = a
    val anotherBoxedA: Int? = a
    
    val b: Int = 128
    val boxedB: Int? = b
    val anotherBoxedB: Int? = b
    
    println(boxedA === anotherBoxedA) // true
    println(boxedB === anotherBoxedB) // false
  • 位运算、除法、布尔……跳过

  • 数组

    数组用Array来表示,与java不同的是,数组自带了get和set函数

    class Array<T> private constructor() {
        val size: Int
        operator fun get(index: Int): T
        operator fun set(index: Int, value: T): Unit
    
        operator fun iterator(): Iterator<T>
        // ……
    }

    创建方式如下:

    val arr = Array(5){
      i - > (i * i).toString()}
    }
    arr.forEach{println(it)} // 打印结果:014916

    kotlin还支持定制了原生类型数组,比如ByteArray,ShortArray,IntArray等,与Array是同级关系

    val x: IntArray = intArrayOf(1, 2, 3)
    x[0] = x[1] + x[2]
  • 字符串

    和java一样,字符串不可变,可以连接,但是只要第一个是字符串,后面接的任何数值都会转为字符串

    val s = "abc" + 1
    println(s + "def") // abc1def

    对于多行字符串,可以使用"""

    val text = """
        for (c in "foo")
            print(c)
    """

类与对象

类与继承

  • 构造函数

    • 主构造函数

      在 Kotlin 中的一个类可以有一个主构造函数以及一个或多个次构造函数。主构造函数是类头的一部分:它跟在类名(与可选的类型参数)后。

      class Person constructor(firstName: String) { /*……*/ }

      如果主构造函数没有任何注解或者可见性修饰符,可以省略这个 constructor 关键字。

      class Person(firstName: String) { /*……*/ }

      主构造函数不能包含任何的代码。初始化的代码可以放到以 init 关键字作为前缀的初始化块(initializer blocks)中。

      在实例初始化期间,初始化块按照它们出现在类体中的顺序执行,

      class InitOrderDemo(name: String) {
          val firstProperty = "First property: $name"
      
          init {
              println("First initializer block that prints ${name}\n")
          }
      
          val secondProperty = "Second property: ${name.length}"
      
          init {
              println("Second initializer block that prints ${name.length}\n")
          }
      }
      InitOrderDemo("hello")
      
      /*
      *打印结果
      *First initializer block that prints hello
      *Second initializer block that prints 5
      */
  • 次构造函数

    class Person {
        var children: MutableList<Person> = mutableListOf<>()
        constructor(parent: Person) {
            parent.children.add(this)
        }
    }

    因为主构造函数初始化代码放在init中,所以init中的代码总是优先constructor执行

    class Constructors {
        constructor(i: Int) {
            println("Constructor")
        }
        init {
            println("Init block\n")
        }
    }
    Constructors(1)
  • 创建类的实例

    kotlin是真正意义的万物皆对象,类对象,函数都可以放到变量中

    val classdemo = ClasesDemo() 
  • 继承

    java中的默认超类是Object,kotlin中是Any

    与变量中kotlin默认为非空类似,kotlin的类默认都是不可继承的,相当于加了java中的final,又与java相反,要想继承kotlin的类,必须显示增加open关键字

    open class Base (a : Int)// 该类开放继承
    class Derived(a : Int) : Base(a)

    除此之外,凡是需要被覆盖的方法和属性,都必须显示的声明open,而覆盖方法也需要显示声明override

    open class Shape {
        open fun draw() { /*……*/ }
        fun fill() { /*……*/ }
    }
    
    class Circle() : Shape() {
        override fun draw() { /*……*/ }
    }

小问题:var和val如何互相覆盖?

kotlin支持多重继承,如果继承了不同的类的相同方法,需要显示提供这个实现,并且提供自己的实现,使用尖括号来区分

  open class Rectangle {
      open fun draw() { /* …… */ }
  }

  interface Polygon {
      fun draw() { /* …… */ } // 接口成员默认就是“open”的
  }

  class Square() : Rectangle(), Polygon {
      // 编译器要求覆盖 draw():
      override fun draw() {
          super<Rectangle>.draw() // 调用 Rectangle.draw()
          super<Polygon>.draw() // 调用 Polygon.draw()
      }
  }
  • 抽象类

    在类前添加abstract关键字即可

    open class Polygon {
        open fun draw() {}
    }
    abstract class Rectangle : Polygon() {
        abstract override fun draw()
    }
  • 伴生对象

    在java的类中,往往很多常量和变量都是static的,但是kotlin没有static,替换成了伴生对象

    java中

    public class Sample {
        public static final int CONST_NUMBER = 1;
    }

    kotlin中

    class Sample {
        companion object {
            const val CONST_NUMBER = 1
        }
    }
    const val CONST_SECOND_NUMBER = 2

    这里object是一个可以独立使用的关键字,和class一样可以创建类,区别是,他是默认单例

    object Sample {
        val name = "A name"
    }

    相比起java需要sychronized关键字,kotlin的单例非常简单通过类名就可以访问属性 Sample.name

    小问题:java和中声明为statci final 的类真的没有办法变化吗?

函数与lambda表达式

集合

协程

全部评论

相关推荐

一天代码十万三:这都不能算简历吧
点赞 评论 收藏
分享
从输入URL到页面加载发生了什么:总体来说分为以下几个过程:&nbsp;1.DNS解析&nbsp;2.TCP连接&nbsp;3.发送HTTP请求&nbsp;4.服务器处理请求并返回HTTP报文&nbsp;5.浏览器解析渲染页面&nbsp;6.连接结束。简述了一下各个过程的输入输出作用:以下是对从输入&nbsp;URL&nbsp;到页面加载各过程的输入、输出或作用的一句话描述:DNS&nbsp;解析:&nbsp;输入:用户在浏览器地址栏输入的域名(如&nbsp;www.example.com)。输出:对应的&nbsp;IP&nbsp;地址(如&nbsp;192.168.1.1)。作用:将易于记忆的域名转换为计算机能够识别和用于网络通信的&nbsp;IP&nbsp;地址,以便浏览器与目标服务器建立连接。TCP&nbsp;连接:&nbsp;输入:浏览器获得的服务器...
明天不下雨了:参考一下我的说法: 关键要讲出输入网址后涉及的每一个网络协议的工作原理和作用: 涉及到的网络协议: HTTP/HTTPS协议->DNS协议->TCP协议->IP协议->ARP协议 面试参考回答: 第一次访问(本地没有缓存时): 一般我们在浏览器地址栏输入的是一个域名。 浏览器会先解析 URL、解析出域名、资源路径、端口等信息、然后构造 HTTP 请求报文。浏览器新开一个网络线程发起HTTP请求(应用层) 接着进行域名解析、将域名解析为 IP 地址 浏览器会先检查本地缓存(包括浏览器 DNS 缓存、操作系统缓存等)是否已解析过该域名 如果没有、则向本地 DNS 服务器请求解析; 本地服务器查不到会向更上层的 DNS 服务器(根域名服务器->顶级域名服务器->权威域名服务器询问)递归查询 最终返回该域名对应的 IP 地址。(应用层DNS协议)DNS 协议的作用: 将域名转换为 IP 地址。 由于 HTTP 是基于 TCP 传输的、所以在发送 HTTP 请求前、需要进行三次握手、在客户端发送第一次握手的时候、( 浏览器向服务器发送一个SYN(同步)报文、其中包含客户端的初始序列号。TCP头部设置SYN标志位、并指定客户端端口 同时填上目标端口和源端口的信息。源端口是浏览器随机生成的、目标端口要看是 HTTP 还是 HTTPS、如果是 HTTP 默认目标端口是 80、如果是 HTTPS 默认是 443。(传输层) 然后到网络层:涉及到(IP协议) 会将TCP报文封装成IP数据包、添加IP头部,包含源IP地址(浏览器)和目标IP地址(服务器)。IP 协议的作用: 提供无连接的、不可靠的数据包传输服务。 然后到数据链路层、会通过 ARP 协议、获取目标的路由器的 MAC 地址、然后会加上 MAC 头、填上目标 MAC 地址和源 MAC 地址。 然后到物理层之后、直接把数据包、转发给路由器、路由器再通过下一跳、最终找到目标服务器、然后目标服务器收到客户的 SYN 报文后,会响应第二次握手。 当双方都完成三次握手后、如果是 HTTP 协议、客户端就会将 HTTP 请求就会发送给目标服务器。如果是 HTTPS 协议、客户端还要和服务端进行 TLS 四次握手之后、客户端才会将 HTTP 报文发送给目标服务器。 目标服务器收到 HTTP 请求消息后、就返回 HTTP 响应消息、浏览器会对响应消息进行解析渲染、呈现给用户
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务