interface Shape {
fun draw()
}
class Circle:Shape{
override fun draw() {
println("Shape: Circle")
}
}
class Rectangle:Shape{
override fun draw() {
println("Shape: Rectangle")
}
}
open class ShapeDecorator(private val decoratedShape: Shape):Shape{
override fun draw() {
decoratedShape.draw()
}
}
class RedShapeDecorator( decoratedShape: Shape):ShapeDecorator(decoratedShape){
override fun draw() {
super.draw()
println("Border Color: Red")
}
}
class DecoratorPatternDemo{
fun main(){
val circle: Shape = Circle()
val rectangle = Rectangle()
val redCircle: ShapeDecorator = RedShapeDecorator(circle)
val redRectangle: ShapeDecorator = RedShapeDecorator(rectangle)
println("Circle with normal border")
circle.draw()
println("Circle of red border")
redCircle.draw()
println("Rectangle of red border")
redRectangle.draw()
}
}
复制代码
执行结果:
Circle with normal border
Shape: Circle
Circle of red border
Shape: Circle
Border Color: Red
Rectangle of red border
Shape: Rectangle
Border Color: Red
复制代码
interface Shape {
fun draw()
}
class Circle:Shape{
override fun draw() {
println("Shape: Circle")
}
}
class Rectangle:Shape{
override fun draw() {
println("Shape: Rectangle")
}
}
class Square:Shape{
override fun draw() {
println("Shape: Square")
}
}
class ShapeMaker{
private val circle = Circle()
private val rectangle = Rectangle()
private val square = Square()
fun drawCircle() {
circle.draw()
}
fun drawRectangle() {
rectangle.draw()
}
fun drawSquare() {
square.draw()
}
}
class FacadePatternDemo{
fun main(){
val shapeMaker = ShapeMaker()
shapeMaker.drawCircle()
shapeMaker.drawRectangle()
shapeMaker.drawSquare()
println("I'll draw a border in a second")
}
}
复制代码
执行结果:
Shape: Circle
Shape: Rectangle
Shape: Square
I'll draw a border in a second
复制代码
写道这里,我想起了《一代宗师》有人问叶问说:
“咏春有什么绝招啊?”
叶问答道:“就三板斧:摊、膀、伏。”
那人再问:“人家宫家六十四手千变万化,你们咏春就三板斧。摊、膀、伏,你怎么打啊?”
叶问回答道:“三板斧就够他受的了。”
coding 也是千变万化,只是GoF(Gang of Four,四人帮)对常用的一些变化进行了一些总结,形成了传说中的“剑贰拾叁式”——23种设计模式。而叶问大侠就是仅靠武术里的三招常用的招式进行组合成为了一代宗师!(如果你们谁和叶问到有切磋过,麻烦告诉我,叶问会几招几式?)所以要想成为大侠,还是得把基础的招式练好,并做到随机应变,看来我的路还比较长!
3. 高阶语法的笑话
说到笑话之前,大家先看看一开始我说的这个工具类
class PreferenceUtil<T>(val name: String, private val default: T) {
private val prefs: SharedPreferences by lazy { BaseApplication.getInstance().getSharedPreferences(name, Context.MODE_PRIVATE) }
operator fun getValue(thisRef: Any?, property: KProperty<*>): T {
return getSharePreferences(name, default)
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
putSharePreferences(name, value)
}
@SuppressLint("CommitPrefEdits")
fun putSharePreferences(name: String, value: T) = with(prefs.edit()) {
when (value) {
is Long -> putLong(name, value)
is String -> putString(name, value)
is Int -> putInt(name, value)
is Boolean -> putBoolean(name, value)
is Float -> putFloat(name, value)
else -> throw IllegalArgumentException("This type of data cannot be saved!")
}.apply()
}
@Suppress("UNCHECKED_CAST")
fun getSharePreferences(name: String, default: T): T = with(prefs) {
val res: Any = when (default) {
is Long -> getLong(name, default)
// 正常情况下是不需要非空断言,但是我的 AS 就是给我穿小鞋
is String -> getString(name, default)!!
is Int -> getInt(name, default)
is Boolean -> getBoolean(name, default)
is Float -> getFloat(name, default)
else -> throw IllegalArgumentException("This type of data cannot be saved!")
}
return res as T
}
}
复制代码
public class NotImplementedError(message: String = "An operation is not implemented.") : Error(message)
@kotlin.internal.InlineOnly
public inline fun TODO(): Nothing = throw NotImplementedError()
@kotlin.internal.InlineOnly
public inline fun TODO(reason: String): Nothing = throw NotImplementedError("An operation is not implemented: $reason")
复制代码
以上代码不用注释都能看明白,当运行到TODO()或者TODO("**")的时候,代码会抛出一个Error,信息是An operation is not implemented.或者是**。
入门真是小case,接下来我们正式开始进入第一关run()函数。
3.1 run()函数
/**
* Calls the specified function [block] and returns its result.
*
* For detailed usage information see the documentation for [scope functions](https://kotlinlang.org/docs/reference/scope-functions.html#run).
*/
@kotlin.internal.InlineOnly
public inline fun <R> run(block: () -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block()
}
复制代码
// 示例类
class MultiportService(var url: String, var port: Int) {
fun prepareRequest(): String = "Default request"
fun query(request: String): String = "Result for query '$request'"
}
// 调用
fun main() {
val service = MultiportService("https://example.kotlinlang.org", 80)
val result = service.run {
port = 8080
query(prepareRequest() + " to port $port")
}
println(result)
}
复制代码
执行结果:
Result for query 'Default request to port 8080'
复制代码
无receiver对象调用run函数
// 调用
fun main() {
val testValue = run {
val a = 5
val b = 3
return@run 3*5
}
val array = intArrayOf(1,2,3,4,5)
for (i in array) {
println(i*testValue)
}
}
复制代码
/**
* Calls the specified function [block] with the given [receiver] as its receiver and returns its result.
*
* For detailed usage information see the documentation for [scope functions](https://kotlinlang.org/docs/reference/scope-functions.html#with).
*/
@kotlin.internal.InlineOnly
public inline fun <T, R> with(receiver: T, block: T.() -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return receiver.block()
}
复制代码
fun main() {
val numbers = mutableListOf("one", "two", "three")
with(numbers) {
println("'with' is called with argument $this")
println("It contains $size elements")
}
}
复制代码
执行结果:
'with' is called with argument [one, two, three]
It contains 3 elements
复制代码
代码:
fun main() {
val numbers = mutableListOf("one", "two", "three")
val firstAndLast = with(numbers) {
"The first element is ${first()}," +
" the last element is ${last()}"
}
println(firstAndLast)
复制代码
执行结果:
The first element is one, the last element is three
复制代码
/**
* Calls the specified function [block] with `this` value as its receiver and returns `this` value.
*
* For detailed usage information see the documentation for [scope functions](https://kotlinlang.org/docs/reference/scope-functions.html#apply).
*/
@kotlin.internal.InlineOnly
public inline fun <T> T.apply(block: T.() -> Unit): T {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block()
return this
}
复制代码
/**
* Calls the specified function [block] with `this` value as its argument and returns `this` value.
*
* For detailed usage information see the documentation for [scope functions](https://kotlinlang.org/docs/reference/scope-functions.html#also).
*/
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
public inline fun <T> T.also(block: (T) -> Unit): T {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block(this)
return this
}
复制代码
fun main() {
val numbers = mutableListOf("one", "two", "three")
numbers
.also { println("The list elements before adding new one: $it") }
.add("four")
println(numbers.toString())
}
复制代码
执行结果:
The list elements before adding new one: [one, two, three]
[one, two, three, four]
复制代码
文档很给力,我们看下一个!
3.4 let()函数
先看看源码,特别提醒与run()函数的源码对比着看。
/**
* Calls the specified function [block] with `this` value as its argument and returns its result.
*
* For detailed usage information see the documentation for [scope functions](https://kotlinlang.org/docs/reference/scope-functions.html#let).
*/
@kotlin.internal.InlineOnly
public inline fun <T, R> T.let(block: (T) -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block(this)
}
复制代码
fun main(){
val numbers = mutableListOf("one", "two", "three", "four", "five")
val resultList = numbers.map { it.length }.filter { it > 3 }
println(resultList)
// 在调用链的结果上调用一个或多个函数
numbers.map { it.length }.filter { it > 3 }.let {
println(it)
// and more function calls if needed
}
}
复制代码
运行结果:
[5, 4, 4]
[5, 4, 4]
复制代码
示例『2』
fun main(){
val numbers = mutableListOf("one", "two", "three", "four", "five")
val resultList = numbers.map { it.length }.filter { it > 3 }
println(resultList)
// reference(::)代替lambda
numbers.map { it.length }.filter { it > 3 }.let(::println)
}
复制代码
运行结果:(和示例『1』一样的动作,故结果也是一样)
[5, 4, 4]
[5, 4, 4]
复制代码
示例『3』
var a:String? = null
fun main(){
a?.let {
println("$a 对象不为空,干活吧!")
}?: println("对象为空,无法面向对象编程")
}
复制代码
运行结果:
对象为空,无法面向对象编程
复制代码
示例『4』——引入局部变量,改善代码可读性
val list:MutableList<List<String>?>? = mutableListOf()
fun main(){
val numbers = listOf("one", "two", "three", "four")
list?.add(numbers)
val modifiedFirstItem = list?.let {
it.first()?.let { list ->
list.first().let { firstItem ->
println("The first item of the list is '$firstItem'")
if (firstItem.length >= 5) firstItem else "!$firstItem!"
}.toUpperCase()
}
}
println("First item after modifications: '$modifiedFirstItem'")
}
复制代码
执行结果:
The first item of the list is 'one'
First item after modifications: '!ONE!'
复制代码
/**
* Returns `this` value if it satisfies the given [predicate] or `null`, if it doesn't.
*/
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
public inline fun <T> T.takeIf(predicate: (T) -> Boolean): T? {
contract {
callsInPlace(predicate, InvocationKind.EXACTLY_ONCE)
}
return if (predicate(this)) this else null
}
复制代码
这里没有文档,我们直接看注释:
Returns `this` value if it satisfies the given [predicate] or `null`, if it doesn't
如果满足给定的[predicate],则返回上下文的'this';如果不满足给定的[predicate],则返回' null '。
复制代码
fun main(){
val students = intArrayOf(99,100,72,48,61)
val result = students.map {
val gradle = it.takeIf { grade ->
return@takeIf grade>= 60
}
return@map if(gradle != null) "及格" else "不及格"
}
println(result.toString())
}
复制代码
执行结果:
[及格, 及格, 及格, 不及格, 及格]
复制代码
3.5.3 takeUnless()函数
这个函数和takeIf()函数是一对的,还是先看源码:
/**
* Returns `this` value if it _does not_ satisfy the given [predicate] or `null`, if it does.
*/
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
public inline fun <T> T.takeUnless(predicate: (T) -> Boolean): T? {
contract {
callsInPlace(predicate, InvocationKind.EXACTLY_ONCE)
}
return if (!predicate(this)) this else null
}
复制代码
翻译注释:
Returns `this` value if it _does not_ satisfy the given [predicate] or `null`, if it does.
如果不满足给定的[谓词],则返回' this '值;如果满足给定的[谓词],则返回' null '。
复制代码
这个比较简单了,和takeIf()函数是相反的,因此我们直接上示例代码:
fun main(){
val students = intArrayOf(99,100,72,48,61)
val result = students.map {
val gradle = it.takeIf { grade ->
// 请特别注意这里的条件判断
return@takeIf grade < 60
}
return@map if(gradle != null) "及格" else "不及格"
}
println(result.toString())
}
复制代码
执行结果:
[及格, 及格, 及格, 不及格, 及格]
复制代码
3.5.4 repeat()函数
如果上面完全看明白了,这部分应该完全不是问题,我们看源码:
/**
* Executes the given function [action] specified number of [times].
*
* A zero-based index of current iteration is passed as a parameter to [action].
*
* @sample samples.misc.ControlFlow.repeat
*/
@kotlin.internal.InlineOnly
public inline fun repeat(times: Int, action: (Int) -> Unit) {
contract { callsInPlace(action) }
for (index in 0 until times) {
action(index)
}
}
复制代码
翻译注释:
Executes the given function [action] specified number of [times].
执行给定的函数[操作]指定的次数[次]。
A zero-based index of current iteration is passed as a parameter to [action].
当前迭代的从零开始的索引作为参数传递给[action]。
复制代码
这个比较简单,我们看示例和运算结果:
fun main(){
repeat(10){
println("我是重复的第${it + 1}次,我的索引为:$it")
}
}
复制代码
class EasySharedPreferences{
companion object{
@JvmStatic
fun <E>getSPValue(key: String, default: E):E{
val result:E by PreferenceUtil(key, default)
return result
}
@JvmStatic
fun <E>putSPValue(key: String, value: E){
var old:E by PreferenceUtil(key, value)
old = value
}
}
}
// 调用示例
// put
EasySharedPreferences.putSPValue("key","value")
// get
EasySharedPreferences.getSPValue("key","default")
复制代码