草庐IT

Kotlin 基础学习 (一) 关键字

笨鱼天阳 2023-09-17 原文

Kotlin
线上编写练习
Kotlin官网提供了 PlayGround 供大家线上尝试
地址:https://play.kotlinlang.org/

原文:https://blog.csdn.net/CrazyApes/article/details/126941878

@[toc]

前言

本来没打算把关键字介绍放在第一部分,可是发现,如果不放在这儿,后面很多用到关键字的地方会有很多不明白不了解的情况。

所以还是把关键字的介绍放在了第一部分,不需要全部记住,但是在后面看到的时候,可以随时翻到这篇文章,可以做一个简单的了解。

本文简单的介绍了Kotlin中使用的部分常用关键字。
并从官网提供的示例,或者源码示例,亦或者平时的一些使用示例,整理了一部分使用方式方便大家查看。
希望对大家初步了解Kotlin有所帮助。

关键字

Kotlin 官网文档
Keywords
https://kotlinlang.org/docs/keyword-reference.html

Kotlin 的关键字大致可以分为以下几种:

  • Hard keywords 硬关键字
    任何情况下都被优先解析为关键字,不可以作为任何标识符。
  • Soft keywords 软关键字
    在某些起作用的上下文中作为关键字,在其不起作用的上下文中可以作为标识符使用。
  • Modifier keywords 修饰符关键字
    可以作为修饰符的关键字,也可以在其它地方用作标识符
  • Special identifiers 特殊标识符
    可以由编译器在特定上下文中定义,它们可以在其他上下文中用作常规标识符
  • Operators and special symbols 运算符和特殊符号
    一些常见运算符和特殊符号

硬关键字 Hard Keywords

Kotlin 官网文档
Hard Keywords
https://kotlinlang.org/docs/keyword-reference.html#hard-keywords

下面的这些符号任何情况下都被优先解析为关键字,不可以作为任何标识符。

// 数据类型转换 
val obj: Any = 1
// 可能会抛出 java.lang.ClassCastException,可以考虑 is 或者 as? 替代
val intValue: Int = obj as Int 

// 处理Nullable
val intValueNullable: Int? = obj as? Int
// is 之后可以直接使用对应属性
if (obj is Int) {
    print("${obj.plus(1)}")
}
==================================================
// import 别名设置
import com.unluck.ktdemo.DemoClass
import com.unluck.ktdemo.bean.DemoClass as DemoBean // 同时引入DemoClass会冲突,可以考虑通过别名引入
//  空安全,但是需要处理 Nullable
val obj: Any? = null
val intValueNullable: Int? = obj as? Int
// break 终止 for
for (i in 1..100) {
    if (...) break
}

// break to labels 可以声明labels 终止指定的for循环
breakToThis@ for (i in 1..100) {
    for (j in 1..100) {
        if (...) break@breakToThis // 终止 breakToThis@ for(i)
    }
}
// 声明类 DemoClass 
class DemoClass {} 
// 声明类 MainActivity 并继承自 AppCompatActivity
class MainActivity : AppCompatActivity() 
 // 声明类 DemoTextView 并继承自 AppCompatTextView
class DemoTextView(ctx : Context) : AppCompatTextView(ctx)
// 声明数据类 DemoBean 并实现 Serializable 接口
data class DemoBean(val name: String) : Serializable
// 同break使用方式类似
for (i in 1..100) {
    if (...) continue
} 

// continue to labels 可以声明labels 继续指定的for循环的下一个循环
continueToThis@ for (i in 1..100) {
    for (j in 1..100) {
        if (...) continue@continueToThis
    }
}
do {
    ...
} while (true)
  • else 定义一个 if 表达式 的 false 时的执行分支.
if (...) 
    ... 
else 
    ...
val bool : Boolean = false
for (i in 1..100) {
    print("print i = $i")
} 
fun mainFunction() {
    ...
}
if (i == 0) ... 
// for 迭代
for (i in 6 downTo 0 step 2) {
    println(i)
}

// check in range
if (3 in 0..4)

// check contains
val list = arrayListOf<Any>()
if ( "1" in list ) {
    ...
}

// when branch
val num = 3
when {
    num in 0..4 -> print("the num $num is in range 0-4")
    else -> {}
}

// 逆变参数
interface Comparable<in T> {
    operator fun compareTo(other: T): Int
}
  • !in
    • 用作 infix 中缀操作符检查值不属于 range, 集合类, 或者其它 定义了 'contains' 方法 的实体类.
    • 一般就是用于 when 表达式的不属于,和上面用于 when 表达式的含义相反.
// check not in range
if (6 !in 0..4)

// check contains
val list = arrayListOf<Any>()
if ( "1" !in list ) {
    ...
}

// when branch
val num = 7
when {
    num !in 0..4 -> print("the num $num is not in range 0-4")
    else -> {}
}

interface Comparable<in T> {
    operator fun compareTo(other: T): Int
}
// check value typecasts
if ( obj is Int) 
    ...

// when branch 
when (value) {
    is GroupMsg -> print("this is group message")
    else -> print("other message")
}

  • !is

    • 跟上面is功能相对
  • null 就是null啊,表示对象没有任何对象引用.

val nullableValue : Any? = null
// 全局单例
object SingletonClass {
    var mInstanceValue = 999

    fun singletonFunString() = "Singleton Class"
}

// 伴生对象
class DemoUtil {
    companion object {
        @JvmStatic
        fun companionObjectFun() = "this is companion object function"
    }
}

// 对象表达式 -> 某个Any对象
val helloWorld = object {
    val hello = "Hello"
    val world = "World"
    // object expressions extend Any, so `override` is required on `toString()`
    override fun toString() = "$hello $world"
}

// 对象表达式 -> 实现某个接口
window.addMouseListener(object : MouseAdapter() {
    override fun mouseClicked(e: MouseEvent) { /*...*/ }

    override fun mouseEntered(e: MouseEvent) { /*...*/ }
})

// 对象表达式 -> 实现抽象类
open class A(x: Int) {
    public open val y: Int = x
}
interface B { /*...*/ }

val ab: A = object : A(1), B {
    override val y = 15
}
// package 仅代表当前文件所属的 package 属性
// 与 java 相比,其package无需与文件的实际路径相关,但是建议保持一致。
package com.unluck.ktdemo.bean  // file://com/unluck/ktdemo/data
// 同 java 类似,从当前函数返回
fun foo() {
    listOf(1, 2, 3, 4, 5).forEach {
        if (it == 3) return // non-local return directly to the caller of foo() 
        print(it)
    }
    println("this point is unreachable")
} // result -> 12

// 在 forEach 中使用 labels 则类似 continue , 其实 return 的是执行的 lamda 
fun foo() {
    listOf(1, 2, 3, 4, 5).forEach lit@{
        if (it == 3) return@lit // local return to the caller of the lambda - the forEach loop
        print(it)
    }
    print(" done with explicit label")
} // result -> 1245 done with explicit label

// 调用超类方法
class Circle() : Shape() {
     override fun draw() {
        super.draw()
        println("Circle")
    }
}
// 调用超类构造
class DemoView : View {
    constructor(ctx: Context) : super(ctx)
    constructor(ctx: Context, attrs: AttributeSet) : super(ctx, attrs)
}
throw NoBugException()
val bool : Boolean = true
try {
    ...
} catch ( e : Exception) {}
class A {
    inner class Inner
}
class B {
    inner class Inner
}

typealias AInner = A.Inner
typealias BInner = B.Inner
  • typeof 保留关键字,暂时没用,可能以后会用.

  • val 声明不可变变量 (只读) 属性 或者 局部变量.

val finalValue : Int = 1
var variable : Int = 1
when {
    a == b -> {}
    else -> {}
}

when(a) {
    0 -> {}
    else -> {}
}
while (true) {
    ...
}

软关键字 Soft Keywords

Kotlin 官网文档
Soft Keywords
https://kotlinlang.org/docs/keyword-reference.html#soft-keywords

下面的这些符号在其适用的上下文中充当关键字,并且可以在其他上下文中用作标识符。

interface Printer {
    fun print()
}

class DefaultPrinter : Printer {
    override fun print() {
        print("default printer")
    }
}

class DemoFragment : Fragment(), Printer by DefaultPrinter()  { // 委托实现接口
    val vm : ViewModel by viewModels() // 委托属性

    fun doSomePrint() {
        print() // print -> default printer
    }
}
try {
    ...
    throw NoBugException("Yes , NO BUG !!! ")
    ...
} catch (e : NoBugException) {
    print("NO BUG ~ ")
} catch (e2 : Exception) {
    print("F..k !!!! ")
}
class DemoView : View {
    constructor(ctx: Context) : super(ctx) {
        ...
    }
    constructor(ctx: Context, attrs: AttributeSet) : super(ctx, attrs)
}
try {
    ...
} finally {
    // optional finally block
} 
val isEmpty: Boolean
    get() = this.size == 0
import com.unluck.ktdemo.Demo
class Demo {
    init {
        print("init block")
    }
}
var setterVisibility: String = "abc"
    private set // the setter is private and has the default implementation

var setterWithAnnotation: Any? = null
    @Inject set // annotate the setter with Inject
// To declare an inline class, use the value modifier before the name of the class:
value class Password(private val s: String)
fun <T> copyWhenGreater(list: List<T>, threshold: T): List<String>
    where T : CharSequence,
          T : Comparable<T> {
    return list.filter { it > threshold }.map { it.toString() }
}

修饰符关键字 Modifier keywords

Kotlin 官网文档
Modifier keywords
https://kotlinlang.org/docs/keyword-reference.html#modifier-keywords

以下符号作为声明中修饰符列表中的关键字,并可用作其他上下文中的标识符。

  • abstract 标记为 抽象类 或者抽象方法.

  • actual 多平台 实现方式,该标记表明其实现方式可能由其它平台实现.

@SinceKotlin("1.1") public actual typealias RandomAccess = java.util.RandomAccess

@SinceKotlin("1.1") public actual typealias ArrayList<E> = java.util.ArrayList<E>
@SinceKotlin("1.1") public actual typealias LinkedHashMap<K, V> = java.util.LinkedHashMap<K, V>
@SinceKotlin("1.1") public actual typealias HashMap<K, V> = java.util.HashMap<K, V>
@SinceKotlin("1.1") public actual typealias LinkedHashSet<E> = java.util.LinkedHashSet<E>
@SinceKotlin("1.1") public actual typealias HashSet<E> = java.util.HashSet<E>
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION,
        AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.VALUE_PARAMETER,
        AnnotationTarget.EXPRESSION)
@Retention(AnnotationRetention.SOURCE)
@MustBeDocumented
annotation class Fancy
class DemoClass {
    companion object Factory {
        fun create(): DemoClass = DemoClass()
    }
}
const val STATIC_FINAL_STRING: String = "public static final String"
public inline fun <T, R : Comparable<R>> Iterable<T>.sortedBy(crossinline selector: (T) -> R?): List<T> {
    return sortedWith(compareBy(selector))
}
// 编译器会自动为其主构造函数中的属性生成 equals ,hashCode,toString,copy等方法
data class DataBean (
    val name : String = "",
    val age  : Int = 0,
    var nick : String = "",
) : Serializable
enum class Color(val rgb: Int) {
    RED(0xFF0000),
    GREEN(0x00FF00),
    BLUE(0x0000FF)
}
  • expect 将一个声明标记为平台相关, 并期待在平台模块中实现.

  • external 将一个声明标记为不是在 Kotlin 中实现(通过 JNI访问或者在JavaScript中实现).

  • final 禁止 重写方法.

open class Rectangle() : Shape() {
    final override fun draw() { /*...*/ }
}
@file:kotlin.jvm.JvmName("TuplesKt")
package kotlin
public infix fun <A, B> A.to(that: B): Pair<A, B> = Pair(this, that)

// use to 
val pair : Pair<String,String> = "A" to "B"
@file:kotlin.jvm.JvmMultifileClass
@file:kotlin.jvm.JvmName("MapsKt")
@file:OptIn(kotlin.experimental.ExperimentalTypeInference::class)

package kotlin.collections

@SinceKotlin("1.1")
@kotlin.internal.InlineOnly
public inline fun <K, V> hashMapOf(): HashMap<K, V> = HashMap<K, V>()
  • inner 标识 内部类 会持有外部引用.
// kotlin 默认非声明 inner 的 class 为静态内部类
// 因此如需持有外部引用,需要单独添加 inner 标识
class Outer {
    private val outValue: Int = 1
    inner class Inner {
        fun print() = outValue
    }
}

val print = Outer().Inner().print() // print == 1
package kotlin.collections

expect interface RandomAccess

...

internal expect fun copyToArrayImpl(collection: Collection<*>): Array<Any?>

internal expect fun <T> copyToArrayImpl(collection: Collection<*>, array: Array<T>): Array<T>

internal expect fun <T> arrayOfNulls(reference: Array<T>, size: Int): Array<T>
internal expect fun <K, V> Map<K, V>.toSingletonMapOrSelf(): Map<K, V>
internal expect fun <K, V> Map<out K, V>.toSingletonMap(): Map<K, V>
internal expect fun <T> Array<out T>.copyToArrayOfAny(isVarargs: Boolean): Array<out Any?>
class DemoClass {
    lateinit var lateValue : DemoBean

    fun doLateInit() {
        if (!this::lateValue.isInitialized) {
            lateValue = DemoBean()
        }
    }
}
open class Person {
    open fun age() = 10
}
class OldMan : Person() {
    override fun age() = 100
}
  • operator 将方法声明为 重载运算符 或 约定运算.
    Kotlin 约定了一些函数规则,与之对应的有一系列运算符或者其它关键字约定。
    详细可参考官网对应文档,这里不再一一指出。

  • out 标记参数类型为 协变.
    表示告诉编译器,你只操作数据,并不变更消费数据,不关心其类型。

public data class Pair<out A, out B>(
    public val first: A,
    public val second: B
) : Serializable
open class Person {
    open fun age() = 10
}
class OldMan : Person() {
    override fun age() = 100
}
@MainThread
inline fun <reified VM : ViewModel> Fragment.viewModels(
    noinline ownerProducer: () -> ViewModelStoreOwner = { this },
    noinline factoryProducer: (() -> Factory)? = null
) = createViewModelLazy(VM::class, { ownerProducer().viewModelStore }, factoryProducer)
  • sealed 声明一个 密封类 (限制其继承关系).

  • suspend 标识一个方法或者 lamda 可被挂起 (在 协程 中使用).

public suspend fun delay(timeMillis: Long) {
    if (timeMillis <= 0) return // don't delay
    return suspendCancellableCoroutine sc@ { cont: CancellableContinuation<Unit> ->
        cont.context.delay.scheduleResumeAfterDelay(timeMillis, cont)
    }
}
// mutableListOf
public fun <T> mutableListOf(vararg elements: T): MutableList<T> =
    if (elements.size == 0) ArrayList() else ArrayList(ArrayAsCollection(elements, isVarargs = true))

// vararg
val list = mutableListOf(1,2,3,4)

特殊标识符 Special identifiers

Kotlin 官网文档
Modifier keywords
https://kotlinlang.org/docs/keyword-reference.html#special-identifiers

以下标识符由编译器在指定上下文中定义,并且可以用作其他上下文中的常规标识符。

  • field 用在属性访问器内部来引用该 属性.
var counter = 0 // the initializer assigns the backing field directly
    set(value) {
        if (value >= 0)
            field = value  
            // 不可以使用 counter = value ,否则会导致递归调用set ,ERROR StackOverflow
            // ERROR StackOverflow: Using actual name 'counter' would make setter recursive
    }
// 隐式引用
(1..100).random().takeIf { 
    it > 50  // it -> random 得到的 value 
}?.let { 
    // it -> takeIf 函数的 返回值 ,
    print("random num $it")  
}

// 逻辑较多时 或 有嵌套 lamda,还是建议显示的声明其参数
(1..100).random().takeIf { randomNum ->
    randomNum > 50 
}?.let { num ->
    print("random num $num ")  
}

操作符 Operators and special symbols

[Kotlin 官网文档
Operators and special symbols

https://kotlinlang.org/docs/keyword-reference.html#operators-and-special-symbols ](https://kotlinlang.org/docs/keyword-reference.html#operators-and-special-symbols)

Kotlin 以下操作符及部分特殊符号的定义

  • +, -, *, /, % 常见的数学操作符
// mathematical operators
val plus = 1 + 2
val minus = 2 - 1
val times = 2 * 2
val div = 2 / 2
val rem = 1 % 2

// 展开运算符
fun foo(arr : Array<String>) {
    val list = listOf("vararg params", *arr) // 展开运算符 展开数组内容
}
// 赋值
val key : String = "key"

// 默认参数
fun hash(key : String = "") {}
var num = 1
num += 1  // num = 1 + 1 = 2 
num -= 1  // num = 2 - 1 = 1
num *= 8  // num = 1 * 8 = 8
num /= 2  // num = 8 / 2 = 4
num %= 3  // num = 4 % 3 = 1

a++
++a
a--
--a
  • &&, ||, ! 逻辑“与”、“或”、“非”操作符(对于位运算,请使用相应的中缀函数) .
if (nameStr.isNullOrEmpty() || psd.isNullOrBlank()) {
    ...
}
  • ==, != 相等和不等运算符 (非基本类型会直接调用 equals() ).
    Float 和 Double 比较特殊,比如,如果当操作数不是静态类型化为浮点数,调用的就会是对应的equals方法和compareTo方法,会导致以下结果出现。
    a). -0.0 比 0.0小。
    b). NaN被认为与自身相等。
    c). NaN比无穷大都大。
val a = DemoBean()
val b = DemoBean()
a == b // -> a?.equals(b) ?: (b === null)
a != b // -> !(a?.equals(b) ?: (b === null))

// Float or Double 
// 静态化浮点数
print(-0.0f == 0.0f) // true
print(Float.NaN == Float.NaN) // false 
print(Float.NaN > Float.POSITIVE_INFINITY) // false 

// 特殊情况。 当通过非基本类型比较时,会出现以下结果
// 非静态化为浮点数 例如 :Any
val numZero1 : Any = -0.0f
val numZero2 : Any = 0.0f
println(numZero1 == numZero2) // false 通过 equals 比较

// NaN
val firstNaN : Any = Float.NaN
val secondNaN = Float.NaN
println(firstNaN == secondNaN) // true 通过 equals 比较
a === b
a !== b
  • <, >, <=, >= 比较运算符 (非基本类型会调用 compareTo() ).
    Float 和 Double 比较特殊,比如,如果当操作数不是静态类型化为浮点数,调用的就会是对应的equals方法和compareTo方法,会导致以下结果出现。
    a). -0.0 比 0.0小。
    b). NaN被认为与自身相等。
    c). NaN比无穷大都大。
a > b  // a.compareTo(b) > 0
a < b  // a.compareTo(b) < 0
a >= b // a.compareTo(b) >= 0
a <= b // a.compareTo(b) <= 0

// Float 和 Double 存在特殊情况
// 静态化浮点数
print(-0.0f == 0.0f) // true
print(Float.NaN == Float.NaN) // false 
print(Float.NaN > Float.POSITIVE_INFINITY) // false 

// Comparable
val numZero3 : Comparable<Float> = -0.0f
val numZero4 : Float = 0.0f
println(numZero1 < numZero2)  // true 通过 compareTo 比较

// 无穷
val compareNaN : Comparable<Float> = Float.NaN
val positiveInfinity = Float.POSITIVE_INFINITY // 正无穷
println(compareNaN  > positiveInfinity)  // true 通过 compareTo 比较
val item = array[i]
array[i] = value

val value = hashMap[key]
hashMap[key] = value
fun getNum() : Int? {
      return (1..10).random().takeIf { it > 5} // 返回大于 5 的 Int,否则 返回 null
}
val nonNullValue : Int = getNum()!!  // 如果 getNum() 返回 null ,则直接抛 NullPointerException 

  • ?. 执行 空安全调用 (如果调用者非空才调用方法或属性).
fun getNum() : Int? {
      return (1..10).random().takeIf { it > 5} // 返回大于 5 的 Int,否则 返回 null
}
val num : Int? = getNum()
num?.plus(1) 
fun getNum() : Int? {
      return (1..10).random().takeIf { it > 5} // 返回大于 5 的 Int,否则 返回 null
}
val num : Int = getNum() ?: 1  // getNum 为空时,num 等于 右侧的 1
// member
fun isOdd(x: Int) = x % 2 != 0

val numbers = listOf(1, 2, 3)
println(numbers.filter(::isOdd))  // ::isOdd ==> 代表isOdd方法,类型为 block(x) -> Boolean

// class
Intent(this@MainActivity,SecondActivity::class.java)
1..3   // 1,2,3
1..100 // 1,2,3 ... 98,99,100
  • : 分隔声明中的名称与类型.
val name : String = ""
val name : String? = null
// lamda
view.setOnClickListener { view ->
    print("view click")
}
v.setOnTouchListener { view, event -> 
    print("view touch event ${event.action}")
    false
}

// 函数类型
fun check(block : (Boolean) -> Unit) {
    block(true)
    block.invoke(false)
}
check {
    print(it)
}

// when
when(value) {
    0 -> {}
    else -> {}
}
// 注解
@Route(path = "/user/center")
class UserCenterActivity 

// loop label
breakToThis@ for (i in 1..100) {
    for (j in 1..100) {
        if (...) break@breakToThis // 终止 breakToThis@ for(i)
    }
}

// lamda label
fun foo() {
    run loop@{
        listOf(1, 2, 3, 4, 5).forEach {
            if (it == 3) return@loop // non-local return from the lambda passed to run
            print(it)
        }
    }
    print(" done with nested loop")
}

// this
class MainActivity .. {
    inner class Factory {
        fun create() {
            Intent(this@MainActivity,SecondActivity::class.java)
        }
    }
}

// super class
class MainActivity : FragmentActivity... {
    inner class Factory {
        fun create() {
            val intent = Intent(this@MainActivity,SecondActivity::class.java)
            super@MainActivity.startActivity(intent)
        }
    }
}
  • ; 分隔位于同一行的多个语句.
val v = View(context); val t = Timer()
print("num $num ")
print("other ${other.num} ")
  • _ 未使用的参数,可以用该符号替代

// lamda
v.setOnTouchListener { _, _ -> 
    // fix all event
    true
}

// 解构
val (_, status) = getResult()

如果要查看各个运算符的优先级,可以查看 这篇官方文档 .

参考文献

Kotlin 官网文档
Keywords
https://kotlinlang.org/docs/keyword-reference.html

有关Kotlin 基础学习 (一) 关键字的更多相关文章

  1. postman接口测试工具-基础使用教程 - 2

    1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,

  2. 软件测试基础 - 2

    Ⅰ软件测试基础一、软件测试基础理论1、软件测试的必要性所有的产品或者服务上线都需要测试2、测试的发展过程3、什么是软件测试找bug,发现缺陷4、测试的定义使用人工或自动的手段来运行或者测试某个系统的过程。目的在于检测它是否满足规定的需求。弄清预期结果和实际结果的差别。5、测试的目的以最小的人力、物力和时间找出软件中潜在的错误和缺陷6、测试的原则28原则:20%的主要功能要重点测(eg:支付宝的支付功能,其他功能都是次要的)80%的错误存在于20%的代码中7、测试标准8、测试的基本要求功能测试性能测试安全性测试兼容性测试易用性测试外观界面测试可靠性测试二、质量模型衡量一个优秀软件的维度①功能性功

  3. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  4. CAN协议的学习与理解 - 2

    最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总

  5. 深度学习部署:Windows安装pycocotools报错解决方法 - 2

    深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal

  6. ES基础入门 - 2

    ES一、简介1、ElasticStackES技术栈:ElasticSearch:存数据+搜索;QL;Kibana:Web可视化平台,分析。LogStash:日志收集,Log4j:产生日志;log.info(xxx)。。。。使用场景:metrics:指标监控…2、基本概念Index(索引)动词:保存(插入)名词:类似MySQL数据库,给数据Type(类型)已废弃,以前类似MySQL的表现在用索引对数据分类Document(文档)真正要保存的一个JSON数据{name:"tcx"}二、入门实战{"name":"DESKTOP-1TSVGKG","cluster_name":"elasticsear

  7. ruby - Ruby 的 AST 中的 'send' 关键字是什么意思? - 2

    我正在尝试学习Ruby词法分析器和解析器(whitequarkparser)以了解更多有关从Ruby脚本进一步生成机器代码的过程。在解析以下Ruby代码字符串时。defadd(a,b)returna+bendputsadd1,2它导致以下S表达式符号。s(:begin,s(:def,:add,s(:args,s(:arg,:a),s(:arg,:b)),s(:return,s(:send,s(:lvar,:a),:+,s(:lvar,:b)))),s(:send,nil,:puts,s(:send,nil,:add,s(:int,1),s(:int,3))))任何人都可以向我解释生成的

  8. ruby - 我正在学习编程并选择了 Ruby。我应该升级到 Ruby 1.9 吗? - 2

    我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or

  9. ruby - 为什么 return 关键字会导致我的 'if block' 出现问题? - 2

    下面的代码工作正常:person={:a=>:A,:b=>:B,:c=>:C}berson={:a=>:A1,:b=>:B1,:c=>:C1}kerson=person.merge(berson)do|key,oldv,newv|ifkey==:aoldvelsifkey==:bnewvelsekeyendendputskerson.inspect但是如果我在“ifblock”中添加return,我会得到一个错误:person={:a=>:A,:b=>:B,:c=>:C}berson={:a=>:A1,:b=>:B1,:c=>:C1}kerson=person.merge(berson

  10. ruby - 我如何学习 ruby​​ 的正则表达式? - 2

    如何学习ruby​​的正则表达式?(对于假人) 最佳答案 http://www.rubular.com/在Ruby中使用正则表达式时是一个很棒的工具,因为它可以立即将结果可视化。 关于ruby-我如何学习ruby​​的正则表达式?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/1881231/

随机推荐