kotlin读书笔记之函数基本知识以及泛型

本文深入解析Kotlin函数的声明、参数、返回值、泛型及中缀表示法等内容,涵盖智能类型推断、泛型约束与型变等高级特性。

1.函数内容

1.1 函数的声明与用法

kotlin的函数使用fun关键字声明,如下所示:

fun double(x: Int): Int {
    return 2 * x
}
double(2).tostring()

1.2 函数参数

java不一样,kotlin的函数参数采用pascal表示法定义,即 name: type

fun powerOf(number: Int, exponent: Int) { /*……*/ }

kotlin可以设置默认参数:

fun read(b: Array<Byte>, off: Int = 0, len: Int = b.size) { /*……*/ }

kotlin可以使用具名称的函数参数。使得代码可读性更强:

reformat(str,
    normalizeCase = true,
    upperCaseFirstLetter = true,
    divideByCamelHumps = false,
    wordSeparator = '_'
)
reformat(str, wordSeparator = '_')

具名参数和位置参数混用的时候,位置参数应该放在具名参数的前面,允许调用 f(1, y = 2) 但不允许 f(x = 1, 2)

可以通过使用星号操作符将可变数量参数(vararg 以具名形式传入:

fun foo(vararg strings: String) { /*……*/ }

foo(strings = *arrayOf("a", "b", "c"))

当覆盖一个带有默认值的方法时,应该省略默认参数值:

open class A {
    open fun foo(i: Int = 10) { /*……*/ }
}

class B : A() {
    override fun foo(i: Int) { /*……*/ }  // 不能有默认值
}

如果要指定某个参数的值,那么可以使用具名参数:

fun foo(bar: Int = 0, baz: Int) { /*……*/ }

foo(baz = 1) // 使用默认值 bar = 0

如果lambda表达式作为参数的最后一个值,那么他可以放在括号外面:

fun foo(bar: Int = 0, baz: Int = 1, qux: () -> Unit) { /*……*/ }

foo { println("hello") }        // 使用两个默认值 bar = 0 与 baz = 1

1.3 函数返回值

1.3.1 返回Unit的函数

Unit相当于java中的void,即不返回任何值。

fun printHello(name: String?): Unit{ …… }
fun printHello(name: String?) { …… }//代码等同于上面

1.3.2 返回单个表达式的函数

返回单个表达式的时候,可以直接把表达式写在等号后面。并且如果返回值类型可以由编译器推断的时候,那么返回值类型可以忽略。

fun double(x: Int): Int = x * 2
fun double(x: Int) = x * 2//Int类型可以省略

1.3.3 显式返回类型

具有块代码体的函数必须始终显式指定返回类型。 Kotlin 不推断具有块代码体的函数的返回类型,因为这样的函数在代码体中可能有复杂的控制流,并且返回类型对于读者(有时甚至对于编译器)是不明显的。

1.4 中缀表示法

中缀表示法有点像C++中的运算符重载。中缀表示法的标有infix关键字,它三个必要条件:

  • 必须是成员函数或扩展函数;
  • 必须只有一个参数;
  • 其参数不得接受可变数量的参数且不能有默认值。
infix fun Int.add(x: Int): Int {
    return this + x
}

fun main(args: Array<String>) {
    println("Result = "+(1 add 2))
}

1.5 函数作用域

1.6 泛型函数

1.6.1 Kotlin的泛型

1.6.1.1 泛型的定义与使用

kotlin泛型的写法和java类似,都是将泛型写在尖括号内,并放在类后面。如下所示:

class Box<T>(t: T) {
    var value = t
}

val box: Box<Int> = Box<Int>(1)

val box = Box(1)//kotlin会自动判断类型

还有一种就是泛型函数,写法类似:

fun <T> singletonList(item: T): List<T> {
    // ……
}

val l = singletonList<Int>(1)

val l = singletonList(1)//kotlin会自动判断类型
1.6.1.2 泛型约束

对应于java泛型中的extend关键字

fun <T:Int> printTest(value:T){
    println("result = "+(value+3))
}

fun main(args: Array<String>) {
    printTest(1)
    // printTest("nothing") //报错:inferred type String is not a subtype of Int
}

如果是需要多个上界的话,那么可以用where来实现

interface A{
    fun printA(infor:String)
}

interface B{
    fun printB(infor:String)
}

fun <T> printTest2(value:T)
where
T:A,
T:B
{
    value.printA("打印A")
    value.printB("打印B")
}
fun main(args: Array<String>) {
    printTest2(object:A,B{
            override fun printA(infor:String){
                println("printA = "+infor)
            }
            override fun printB(infor:String){
                println("printB = "+infor)
            }
        })
}
1.6.1.3 类型擦除

类型擦除指的是泛型声明用法执行的类型安全检测仅在编译期进行。在运行期间不保留实参的任何信息,即无法用as来判断类型。然而有一种例外即内联函数的具体化类型参数。

1.6.2 声明处型变

型变分为两种:协变和逆变。用法分别是在参数前加上out和in。

协变的时候对象是作为生产者,也就是说它只负责产出。逆变的时候对象是作为消费者,它只负责消费。具体代码如下所示:

interface Operation<out T>{
    fun eat():T
}

interface Operation2<in E>{
    fun print(e:E)
}

fun main(args: Array<String>) {
    val A:Operation<Number> = object:Operation<Int>{
        override fun eat():Int{
            return 17
        }
    }

    val B:Operation2<Int> = object:Operation2<Number>{
        override fun print(e:Number){
            println("Operation2")
        }
    }
}

1.6.3 使用处型变

使用处型变也称为类型投影,他是在不变类型上动态做协变或者逆变。

    val list1:MutableList<String> = mutableListOf()
    list1.add("hello")
    list1.add("world")

    val list2:MutableList<out String> = mutableListOf()
    list2.add("hello")  // compile error
    list2.add("world")  // compile error

    val list3:MutableList<in String> = mutableListOf()
    list3.add("hello")
    list3.add("world")

    lateinit var list4:MutableList<String>
    list4 = list3;     // compile error

如上所示MutableList是一个不变对象。当使用out时,list2即变成协变的对象,他不能作为消费者而只能是生产者。对应的当使用in时候,list3就变成了逆变的对象。

1.6.5 星投影

有种场景是参数类型未知,那么星投影的功能就是声明对象的只读特性。
Foo <out T:Tupper>,那么Foo<*>表示的意义就是该对象作为生产者,可以安全的读取读取TUpper 的值。

fun main(args: Array<String>) {
    val star6: Star3<*> = Star3<String>("hello word")
    println(star6.getValue())
}

class Star3<T:CharSequence>(private var t: T) {

    fun getValue(): T {
        return this.t
    }
}

打印出的是"hello word",那么可以理解为out修饰参数的时候,星投影会则输出的是Sting的类。

Foo <in T>,那么Foo<*>表示的意义就是该对象作为消费者,不能写入任何数据。这个好理解,既然类型都不知道,输入什么都是不安全的。也就是只读不能写了。
Foo <T:Tupper>,那么Foo<*>表示的意义就是结合了上面两种场景。写入时候不能安全写入任何数据,读取时只能安全读取 TUpper 的值。

2.总结

总体上感觉kotlin的函数是对java的方法做了几点处理:

优化:比如说弥补了java泛型在只产出或者只消费的场景下无法型变的问题

智能:会在编译的时候就自动判别类型,比如说 val key = 1,key就自动判断为Int类型。这点在java做不到

扩展:引入了内联,以及类似运算符重载的中缀表示法。

接下来继续学习内联函数,扩展函数等其他类型的函数。

需求响应动态冰蓄冷系统与需求响应策略的优化研究(Matlab代码实现)内容概要:本文围绕“需求响应动态冰蓄冷系统与需求响应策略的优化研究”展开,基于Matlab代码实现,重点探讨了冰蓄冷系统在电力需求响应背景下的动态建模与优化调度策略。研究结合实际电力负荷与电价信号,构建系统能耗模,利用优化算法对冰蓄冷系统的运行策略进行求解,旨在降低用电成本、平衡电网负荷,并提升能源利用效率。文中还提及该研究为博士论文复现,涉及系统建模、优化算法应用与仿真验证等关键技术环节,配套提供了完整的Matlab代码资源。; 适合人群:具备一定电力系统、能源管理或优化算法基础,从事科研或工程应用的研究生、高校教师及企业研发人员,尤其适合开展需求响应、综合能源系统优化等相关课题研究的人员。; 使用场景及目标:①复现博士论文中的冰蓄冷系统需求响应优化模;②学习Matlab在能源系统建模与优化中的具体实现方法;③掌握需求响应策略的设计思路与仿真验证流程,服务于科研项目、论文写作或实际工程方案设计。; 阅读建议:建议结合提供的Matlab代码逐模块分析,重点关注系统建模逻辑与优化算法的实现细节,按文档目录顺序系统学习,并尝试调整参数进行仿真对比,以深入理解不同需求响应策略的效果差异。
综合能源系统零碳优化调度研究(Matlab代码实现)内容概要:本文围绕“综合能源系统零碳优化调度研究”,提供了基于Matlab代码实现的完整解决方案,重点探讨了在高比例可再生能源接入背景下,如何通过优化调度实现零碳排放目标。文中涉及多种先进优化算法(如改进遗传算法、粒子群优化、ADMM等)在综合能源系统中的应用,涵盖风光场景生成、储能配置、需求响应、微电网协同调度等多个关键技术环节,并结合具体案例(如压缩空气储能、光热电站、P2G技术等)进行建模与仿真分析,展示了从问题建模、算法设计到结果验证的全流程实现过程。; 适合人群:具备一定电力系统、能源系统或优化理论基础,熟悉Matlab/Simulink编程,从事新能源、智能电网、综合能源系统等相关领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①开展综合能源系统低碳/零碳调度的科研建模与算法开发;②复现高水平期刊(如SCI/EI)论文中的优化模与仿真结果;③学习如何将智能优化算法(如遗传算法、灰狼优化、ADMM等)应用于实际能源系统调度问题;④掌握Matlab在能源系统仿真与优化中的典应用方法。; 阅读建议:建议结合文中提供的Matlab代码与网盘资源,边学习理论模边动手调试程序,重点关注不同优化算法在调度模中的实现细节与参数设置,同时可扩展应用于自身研究课题中,提升科研效率与模精度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值