【Swift】运算符
文章目录
- 术语
- 赋值运算符
- 算数运算符
- 基本四则算术运算符
- 求余运算符
- 一元负号运算符
- 一元正号运算符
- 比较运算符
- 三元运算符
- 空合运算符
- 区间运算符
- 闭区间运算符
- 半开区间运算符
- 单侧区间运算符
- 逻辑运算符
- 逻辑非运算符
- 逻辑与运算符
- 逻辑或运算符
- 逻辑运算符组合计算
- 位运算符
- 运算符优先级
- 使用括号来明确优先级
运算符是检查、改变、合并值的特殊符号或短语。例如,加号(+)将两个数相加(如 let i = 1 + 2)。更复杂的运算例子包括逻辑与运算符 &&(如 if enteredDoorCode && passedRetinaScan)。
Swift 支持大部分标准 C 语言的运算符,且为了减少常见编码错误做了部分改进。如:赋值符(=)不再有返回值,这样就消除了手误将判等运算符(==)写成赋值符导致代码错误的缺陷。算术运算符(+,-,*,/,% 等)的结果会被检测并禁止值溢出,以此来避免保存变量时由于变量大于或小于其类型所能承载的范围时导致的异常结果。当然允许你使用 Swift 的溢出运算符来实现溢出。详情参见 溢出运算符。
Swift 还提供了 C 语言没有的区间运算符,例如 a…<b 或 a…b,这方便我们表达一个区间内的数值。
本章节只描述了 Swift 中的基本运算符,高级运算符 这章会包含 Swift 中的高级运算符,及如何自定义运算符,及如何进行自定义类型的运算符重载。
术语
运算符分为一元、二元和三元运算符:
- 一元运算符对单一操作对象操作(如 -a)。一元运算符分前置运算符和后置运算符,前置运算符需紧跟在操作对象之前(如 !b),后置运算符需紧跟在操作对象之后(如 c!)。
- 二元运算符操作两个操作对象(如 2 + 3),是中置的,因为它们出现在两个操作对象之间。
- 三元运算符操作三个操作对象,和 C 语言一样,Swift 只有一个三元运算符,就是三目运算符(a ? b : c)。
受运算符影响的值叫操作数,在表达式 1 + 2 中,加号 + 是二元运算符,它的两个操作数是值 1 和 2。
赋值运算符
下表列出了 Swift 语言的基本赋值运算:
以下为赋值运算的简单实例:
var A = 10
var B = 20
var C = 100C = A + B
print("C = A + B 结果为:\(C)")C += A
print("C += A 结果为:\(C)")C -= A
print("C -= A 结果为:\(C)")C *= A
print("C *= A 结果为:\(C)")C /= A
print("C /= A 结果为:\(C)")
上述代码输出结果为:
C = A + B 结果为:30
C += A 结果为:40
C -= A 结果为:30
C *= A 结果为:300
C /= A 结果为:30
算数运算符
基本四则算术运算符
Swift 中所有数值类型都支持了基本的四则算术运算符:
运算符 | 描述 | 实例 |
---|---|---|
+ | 加号 | A + B 结果为 30 |
- | 减号 | A − B 结果为 -10 |
* | 乘号 | A * B 结果为 200 |
/ | 除号 | B % A 结果为 0 |
var A = 10
var B = 20print("A + B 结果为:\(A + B)")
print("A - B 结果为:\(A - B)")
print("A * B 结果为:\(A * B)")
print("B / A 结果为:\(B / A)")
A += 1 // 类似 A++
print("A += 1 后 A 的值为 \(A)")
B -= 1 // 类似 B--
print("B -= 1 后 B 的值为 \(B)")
以上代码输出的结果为:
A + B 结果为:30
A - B 结果为:-10
A * B 结果为:200
B / A 结果为:2
A += 1 后 A 的值为 11
B -= 1 后 B 的值为 19
※注意:
与 C 语言和 Objective-C 不同的是,Swift 默认情况下不允许在数值运算中出现溢出情况。但是你可以使用 Swift 的溢出运算符来实现溢出运算(如 a &+ b)。详情参见 溢出运算符。
求余运算符
求余运算符(a %
b)是计算 b 的多少倍刚刚好可以容入 a,返回多出来的那部分(余数)。
我们来谈谈取余是怎么回事,计算 9 % 4,你先计算出 4 的多少倍会刚好可以容入 9 中:
你可以在 9 中放入2个 4,那余数是 1。在 Swift 中可以表达为:
9 % 4 // 等于 1
为了得到 a % b
的结果,%
计算了以下等式,并输出 余数作为结果:
a = (b × 倍数) + 余数
当 倍数取最大值的时候,就会刚好可以容入 a 中。把 9 和 4 代入等式中,我们得 1:9 = (4 × 2) + 1。
同样的方法,我们来计算 -9 % 4:
-9 % 4 // 等于 -1
把 -9 和 4 代入等式,-2 是使 余数 与 -9 同符号时能取到的最大整数:-9 = (4 × -2) + -1,余数是 -1。
※注意:
在对负数 b 求余时,b 的符号会被忽略。这意味着 a % b 和 a % -b 的结果是相同的。
示例:
let a = 9 % 4;
print("a: \(a)");let b = 9 % -4;
print("b: \(b)");let c = -9 % 4;
print("c: \(c)");
以上代码输出的结果为:
a: 1
b: 1
c: -1
一元负号运算符
数值的正负号可以使用前缀 -
(即一元负号符)来切换:
let three = 3
let minusThree = -three // minusThree 等于 -3
let plusThree = -minusThree // plusThree 等于 3, 或 "负负3"print("three: \(three)");
print("minusThree: \(minusThree)");
print("plusThree: \(plusThree)");
上述代码输出结果:
three: 3
minusThree: -3
plusThree: 3
※注意:
一元负号符(-
)写在操作数之前,中间没有空格。
一元正号运算符
一元正号符(+
)不做任何改变地返回操作数的值:
let minusSix = -6
let alsoMinusSix = +minusSix // alsoMinusSix 等于 -6print("minusSix: \(minusSix)");
print("alsoMinusSix: \(alsoMinusSix)");
上述代码输出结果:
minusSix: -6
alsoMinusSix: -6
比较运算符
以下表格列出了 Swift 语言支持的比较运算符,其中变量 A 为 10,变量 B 为 20:
运算符 | 描述 | 实例 |
---|---|---|
== | 等于 | (A == B) 为 false |
!= | 不等于 | (A != B) 为 true |
> | 大于 | (A > B) 为 false |
< | 小于 | (A < B) 为 true |
>= | 大于等于 | (A >= B) 为 false |
<= | 小于等于 | (A <= B) 为 true |
※注意:
Swift 也提供恒等(===
)和不恒等(!==
)这两个比较符来判断两个对象是否引用同一个对象实例。更多细节在 类与结构 章节的恒等运算符部分。
每个比较运算都返回了一个标识表达式是否成立的布尔值:
let a = 1 == 1 // true, 因为 1 等于 1
let b = 2 != 1 // true, 因为 2 不等于 1
let c = 2 > 1 // true, 因为 2 大于 1
let d = 1 < 2 // true, 因为 1 小于2
let e = 1 >= 1 // true, 因为 1 大于等于 1
let f = 2 <= 1 // false, 因为 2 并不小于等于 1print("type of a: \(type(of: a)), a value: \(a)");
print("type of b: \(type(of: b)), a value: \(b)");
print("type of c: \(type(of: c)), a value: \(c)");
print("type of d: \(type(of: d)), a value: \(d)");
print("type of e: \(type(of: e)), a value: \(e)");
print("type of f: \(type(of: f)), a value: \(f)");
上述代码输出结果为:
type of a: Bool, a value: true
type of b: Bool, a value: true
type of c: Bool, a value: true
type of d: Bool, a value: true
type of e: Bool, a value: true
type of f: Bool, a value: false
如果两个元组的元素相同,且长度相同的话,元组就可以被比较。比较元组大小会按照从左到右、逐值比较的方式,直到发现有两个值不等时停止。如果所有的值都相等,那么这一对元组我们就称它们是相等的。例如:
let aa = (1, "zebra") < (2, "apple") // true,因为 1 小于 2
let bb = (3, "apple") < (3, "bird") // true,因为 3 等于 3,但是 apple 小于 bird
let cc = (4, "dog") == (4, "dog") // true,因为 4 等于 4,dog 等于 dogprint("type of aa: \(type(of: aa)), a value: \(aa)");
print("type of bb: \(type(of: bb)), a value: \(bb)");
print("type of cc: \(type(of: cc)), a value: \(cc)");
上述代码输出结果:
type of aa: Bool, a value: true
type of bb: Bool, a value: true
type of cc: Bool, a value: true
当元组中的元素都可以被比较时,你也可以使用这些运算符来比较它们的大小。例如,像下面展示的代码,你可以比较两个类型为 (String, Int) 的元组,因为 Int 和 String 类型的值可以比较。相反,Bool
不能被比较,也意味着存有布尔类型的元组不能被比较。
("blue", -1) < ("purple", 1) // 正常,比较的结果为 true
("blue", false) < ("purple", true) // 错误,因为 < 不能比较布尔类型
※注意:
Swift 标准库只能比较 7个 以内元素的元组比较函数。如果你的元组元素超过 7个 时,你需要自己实现比较运算符。
三元运算符
三元运算符的特殊在于它是有三个操作数的运算符,它的形式是 问题 ? 答案 1 : 答案 2
。它简洁地表达根据 问题成立与否作出二选一的操作。如果 问题
成立,返回 答案 1
的结果;反之返回 答案 2
的结果。
三元运算符是以下代码的缩写形式:
if question {answer1
} else {answer2
}
这里有个计算表格行高的例子。如果有表头,那行高应比内容高度要高出 50 点;如果没有表头,只需高出 20 点:
let contentHeight = 40
let hasHeader = true
let rowHeight = contentHeight + (hasHeader ? 50 : 20) // rowHeight 现在是 90
print("rowHeight:\(rowHeight)");
上述代码输出的结果是:
rowHeight:90
上面的写法比下面的代码更简洁:
let contentHeight = 40
let hasHeader = true
var rowHeight = contentHeight
if hasHeader {rowHeight = rowHeight + 50
} else {rowHeight = rowHeight + 20
}
// rowHeight 现在是 90
第一段代码例子使用了三元运算,所以一行代码就能让我们得到正确答案。这比第二段代码简洁得多,无需将 rowHeight 定义成变量,因为它的值无需在 if 语句中改变。
三元运算为二选一场景提供了一个非常便捷的表达形式。不过需要注意的是,滥用三元运算符会降低代码可读性。所以我们应避免在一个复合语句中使用多个三元运算符。
空合运算符
空合运算符(a ?? b
)将对可选类型 a 进行空判断,如果 a 包含一个值就进行解包,否则就返回一个默认值 b。表达式 a 必须是 Optional
类型。默认值 b 的类型必须要和 a 存储值的类型保持一致。
空合运算符是对以下代码的简短表达方法:
a != nil ? a! : b
上述代码使用了三元运算符。当可选类型 a 的值不为空时,进行强制解包(a!
),访问 a 中的值;反之返回默认值 b。无疑空合运算符(??
)提供了一种更为优雅的方式去封装条件判断和解包两种行为,显得简洁以及更具可读性。
※注意:
如果 a 为非空值(non-nil),那么值 b 将不会被计算。这也就是所谓的短路求值。
下文例子采用空合运算符,实现了在默认颜色名和可选自定义颜色名之间抉择:
let defaultColorName = "red"
var userDefinedColorName: String? //默认值为 nilvar colorNameToUse = userDefinedColorName ?? defaultColorName // userDefinedColorName 的值为空,所以 colorNameToUse 的值为 "red"
print("colorNameToUse 值为: \(colorNameToUse)")
上述代码输出的结果为:
colorNameToUse 值为: red
userDefinedColorName 变量被定义为一个可选的 String 类型,默认值为 nil。由于 userDefinedColorName 是一个可选类型,我们可以使用空合运算符去判断其值。在上一个例子中,通过空合运算符为一个名为 colorNameToUse 的变量赋予一个字符串类型初始值。 由于 userDefinedColorName 值为空,因此表达式 userDefinedColorName ?? defaultColorName 返回 defaultColorName 的值,即 red。
如果你分配一个非空值(non-nil)给 userDefinedColorName,再次执行空合运算,运算结果为封包在 userDefinedColorName 中的值,而非默认值。
userDefinedColorName = String()
userDefinedColorName = "yellow"colorNameToUse = userDefinedColorName ?? defaultColorName
print("colorNameToUse 值为: \(colorNameToUse)") // userDefinedColorName 的值不为空,所以 colorNameToUse 的值为 "yellow"
上述代码输出的结果为:
colorNameToUse 值为: yellow
区间运算符
闭区间运算符
闭区间运算符(a...b
)定义一个包含从 a 到 b(包括 a 和 b)的所有值的区间。a 的值不能超过 b。闭区间运算符在迭代一个区间的所有值时是非常有用的,如在 for-in 循环中:
for index in 1...5 {print("\(index) * 5 = \(index * 5)")
}
上述代码输出结果为:
1 * 5 = 5
2 * 5 = 10
3 * 5 = 15
4 * 5 = 20
5 * 5 = 25
半开区间运算符
半开区间运算符(a..<b
)定义一个从 a 到 b 但不包括 b 的区间。 之所以称为半开区间,是因为该区间包含第一个值而不包括最后的值。
半开区间的实用性在于当你使用一个从 0 开始的列表(如数组)时,非常方便地从0数到列表的长度。
let names = ["Anna", "Alex", "Brian", "Jack"]
let count = names.count
for i in 0..<count {print("第 \(i + 1) 个人叫 \(names[i])")
}
上述代码输出结果为:
第 1 个人叫 Anna
第 2 个人叫 Alex
第 3 个人叫 Brian
第 4 个人叫 Jack
单侧区间运算符
闭区间操作符有另一个表达形式,可以表达往一侧无限延伸的区间 —— 例如,一个包含了数组从索引 2 到结尾的所有值的区间。在这些情况下,你可以省略掉区间操作符一侧的值。这种区间叫做单侧区间,因为操作符只有一侧有值。例如:
let names = ["Anna", "Alex", "Brian", "Jack"]for name in names[2...] {print("[2...] -- \(name)");
}for name in names[...2] {print("[...2] -- \(name)");
}
上述代码输出结果为:
[2...] -- Brian
[2...] -- Jack[...2] -- Anna
[...2] -- Alex
[...2] -- Brian
半开区间操作符也有单侧表达形式,附带上它的最终值。就像你使用区间去包含一个值,最终值并不会落在区间内。例如:
for name in names[..<2] {print("[..<2] -- \(name)");
}
上述代码输出结果为:
[..<2] -- Anna
[..<2] -- Alex
单侧区间不止可以在下标里使用,也可以在别的情境下使用。你不能遍历省略了初始值的单侧区间,因为遍历的开端并不明显。你可以遍历一个省略最终值的单侧区间;然而,由于这种区间无限延伸的特性,请保证你在循环里有一个结束循环的分支。你也可以查看一个单侧区间是否包含某个特定的值,就像下面展示的那样:
let range = ...5
let result1 = range.contains(7) // false
let result2 = range.contains(4) // true
let result3 = range.contains(-1) // trueprint("result1: \(result1)")
print("result2: \(result2)")
print("result3: \(result3)")
上述代码输出结果为:
result1: false
result2: true
result3: true
逻辑运算符
逻辑运算符的操作对象是逻辑布尔值。Swift 支持基于 C 语言的三个标准逻辑运算。
- 逻辑非(
!
a) - 逻辑与(a
&&
b) - 逻辑或(a
||
b)
逻辑非运算符
逻辑非运算符(!
a)对一个布尔值取反,使得 true
变 false
,false
变 true
。
它是一个前置运算符,需紧跟在操作数之前,且不加空格。读作 非 a ,例子如下:
let allowedEntry = false
if !allowedEntry {print("ACCESS DENIED")
}
// 输出“ACCESS DENIED”
上述代码输出结果为:
ACCESS DENIED
if !allowedEntry
语句可以读作「如果非 allowedEntry」,接下一行代码只有在「非 allowedEntry」为 true,即 allowEntry 为 false 时被执行。
在示例代码中,小心地选择布尔常量或变量有助于代码的可读性,并且避免使用双重逻辑非运算,或混乱的逻辑语句。
逻辑与运算符
逻辑与运算符(a &&
b)表达了只有 a 和 b 的值都为 true 时,整个表达式的值才会是 true。
只要任意一个值为 false,整个表达式的值就为 false。事实上,如果第一个值为 false,那么是不去计算第二个值的,因为它已经不可能影响整个表达式的结果了。这被称做短路计算(short-circuit evaluation)。
以下例子,只有两个 Bool 值都为 true 的时候才允许进入 if:
let enteredDoorCode = true
let passedRetinaScan = false
if enteredDoorCode && passedRetinaScan {print("Welcome!")
} else {print("ACCESS DENIED")
}
// 输出“ACCESS DENIED”
上述代码输出结果为:
ACCESS DENIED
逻辑或运算符
逻辑或运算符(a ||
b)是一个由两个连续的 | 组成的中置运算符。它表示了两个逻辑表达式的其中一个为 true,整个表达式就为 true。
同逻辑与运算符类似,逻辑或也是「短路计算」的,当左端的表达式为 true 时,将不计算右边的表达式了,因为它不可能改变整个表达式的值了。
以下示例代码中,第一个布尔值(hasDoorKey)为 false,但第二个值(knowsOverridePassword)为 true,所以整个表达是 true,于是允许进入:
let hasDoorKey = false
let knowsOverridePassword = true
if hasDoorKey || knowsOverridePassword {print("Welcome!")
} else {print("ACCESS DENIED")
}
// 输出“Welcome!”
上述代码输出结果为:
Welcome!
逻辑运算符组合计算
我们可以组合多个逻辑运算符来表达一个复合逻辑:
let enteredDoorCode = true
let passedRetinaScan = false
let hasDoorKey = false
let knowsOverridePassword = trueif enteredDoorCode && passedRetinaScan || hasDoorKey || knowsOverridePassword {print("Welcome!")
} else {print("ACCESS DENIED")
}
// 输出“Welcome!”
上述代码输出结果为:
Welcome!
※注意:
Swift 逻辑操作符&&
和||
是左结合的,这意味着拥有多元逻辑操作符的复合表达式优先计算最左边的子表达式。
位运算符
位运算符用来对二进制位进行操作,~,&,|,^分别为取反,按位与与,按位与或,按位与异或运算,如下表实例:
p | q | p & q | p | q | p^q |
---|---|---|---|---|
0 | 0 | 0 | 0 | 0 |
0 | 1 | 0 | 1 | 1 |
1 | 1 | 1 | 1 | 0 |
1 | 0 | 0 | 1 | 1 |
假设:A = 0011 1100,B = 0000 1101
运算符 | 描述 | 图解 | 实例 |
---|---|---|---|
& | 按位与。按位与运算符& 对两个数进行操作,然后返回一个新的数,这个数的每个位都需要两个输入数的同一位都为1时才为1 | (A & B) 结果为 12,二进制为 00001100 | |
| | 按位或。按位或运算符| 比较两个数,然后返回一个新的数,这个数的每一位设置1的条件是两个输入数的同一位都不为0(即任意一个为1,或都为1) | (A | B) 结果为 61,二进制为 00111101 | |
^ | 按位异或。按位异或运算符^ 比较两个数,然后返回一个数,这个数的每个位设为1的条件是两个输入数的同一位不同,如果相同就设为0 | (A ^ B) 结果为 49,二进制为 00110001 | |
~ | 按位取反运算符~ 对一个操作数的每一位都取反 | (~ A ) 结果为 -61,二进制为 11000011 | |
<< | 按位左移。左移操作符<< 将操作数的所有位向左移动指定的位数 | 下图展示了11111111 << 1(11111111 左移一位)的结果。蓝色数字表示被移动位,灰色表示被丢弃位,空位用橙色的0填充 | A << 2 结果为 240,二进制为 11110000 |
>> | 按位右移。右移操作符>> 将操作数的所有位向右移动指定的位数 | 下图展示了11111111 >> 1(11111111 右移一位)的结果。蓝色数字表示被移动位,灰色表示被丢弃位,空位用橙色的0填充 | A >> 2 结果为 15,二进制为 00001111 |
示例:
func bitwiseOperator() {let A = 60 // 二进制为 0011 1100let B = 13 // 二进制为 0000 1101let binaryA = insertPlaceholderZero(initialString: String(A, radix: 2));let binaryB = insertPlaceholderZero(initialString: String(B, radix: 2));let resultAnd = insertPlaceholderZero(initialString: String(A&B, radix: 2));let resultOr = insertPlaceholderZero(initialString: String(A|B, radix: 2));let resultEctopic = insertPlaceholderZero(initialString: String(A^B, radix: 2));let resultNegation = String(~A, radix: 2);print("\(binaryA) & \(binaryB) 的结果为: \(resultAnd)");print("\(binaryA) | \(binaryB) 的结果为: \(resultOr)");print("\(binaryA) ^ \(binaryB) 的结果为: \(resultEctopic)");print("~\(binaryA) 的结果为: \(resultNegation)");}func insertPlaceholderZero(initialString: String) -> String {var resultString = String();var newInitialString = String();newInitialString = initialString.filter{ $0 != "-" };let bitesNum = Int(newInitialString.count / 8);let placeholderCount = (bitesNum + 1) * 8 - newInitialString.count;for _ in 0 ..< placeholderCount {resultString.append("0");}resultString = resultString + newInitialString;resultString = addSpaceSeparator(initialString: resultString);if (initialString.contains("-")) {resultString.insert(contentsOf: "-", at: resultString.startIndex);}return resultString;}func addSpaceSeparator(initialString: String) -> String {var resultString = String();var characterArray = Array(initialString);characterArray = characterArray.reversed();for index in 0..<initialString.count {let chara = characterArray[index];resultString.insert(chara, at: resultString.startIndex);if ((index + 1) % 4 == 0 && index != (characterArray.count - 1)) {resultString.insert(" ", at: resultString.startIndex);}}return resultString;}
上述代码输出结果为:
0011 1100 & 0000 1101 的结果为: 0000 1100
0011 1100 | 0000 1101 的结果为: 0011 1101
0011 1100 ^ 0000 1101 的结果为: 0011 0001
~0011 1100 的结果为: -111101
运算符优先级
在一个表达式中可能包含多个有不同运算符连接起来的、具有不同数据类型的数据对象;由于表达式有多种运算,不同的运算顺序可能得出不同结果甚至出现错误运算错误,因为当表达式中含多种运算时,必须按一定顺序进行结合,才能保证运算的合理性和结果的正确性、唯一性。
优先级从上到下依次递减,最上面具有最高的优先级,逗号操作符具有最低的优先级。
相同优先级中,按结合顺序计算。大多数运算是从左至右计算,只有三个优先级是从右至左结合的,它们是单目运算符、条件运算符、赋值运算符。
基本的优先级需要记住:
- 指针最优,单目运算优于双目运算。如正负号。
- 先乘除(模),后加减。
- 先算术运算,后移位运算,最后位运算。请特别注意:1 << 3 + 2 & 7 等价于 (1 << (3 + 2))&7
- 逻辑运算最后计算
Swift 运算符优先级 (从高到低):
运算符 | 实例 |
---|---|
位运算符 | >> &<< &>> >> |
乘法运算符 | &* % & * / |
加法运算符 | &+ &- + - ^ |
区间运算符 | …< … |
类型转换运算符 | is as |
nil 的聚合运算 | ?? |
比较运算符 | != > < >= <= === == |
逻辑与运算符 | && |
逻辑或运算符 | || |
波浪箭头 | ~> |
三元运算符 | ?: |
箭头函数 | ( ) |
赋值运算符 | |= %= /= &<<= &>>= &= *= >>= <<= ^= += -= |
使用括号来明确优先级
为了一个复杂表达式更容易读懂,在合适的地方使用括号来明确优先级是很有效的,虽然它并非必要的。在上个关于门的权限的例子中,我们给第一个部分加个括号,使它看起来逻辑更明确:
if (enteredDoorCode && passedRetinaScan) || hasDoorKey || knowsOverridePassword {print("Welcome!")
} else {print("ACCESS DENIED")
}
// 输出“Welcome!”
这括号使得前两个值被看成整个逻辑表达中独立的一个部分。虽然有括号和没括号的输出结果是一样的,但对于读代码的人来说有括号的代码更清晰。可读性比简洁性更重要,请在可以让你代码变清晰的地方加个括号吧!
相关文章:
【Swift】运算符
文章目录 术语赋值运算符算数运算符基本四则算术运算符求余运算符一元负号运算符一元正号运算符 比较运算符三元运算符空合运算符区间运算符闭区间运算符半开区间运算符单侧区间运算符 逻辑运算符逻辑非运算符逻辑与运算符逻辑或运算符逻辑运算符组合计算 位运算符运算符优先级…...
minikube start --driver=docker 指定国内镜像
要在Ubuntu 22上使用Minikube并指定国内镜像,你可以根据以下步骤操作: 安装Minikube: 你可以通过阿里云提供的国内源来安装Minikube,这样可以避免访问国外源的问题。使用以下命令安装Minikube: curl -Lo minikube http…...
Quality minus junk论文阅读
Quality minus junk论文阅读 文章目录 Quality minus junk论文阅读 AbstractTheoretical FrameworkEmpirical AnalysisDataQuality scorePortfoliosEx ante quality forecasts fundamentals Results and DiscussionThe price of qualityUnderstanding the price of quality: th…...
Apache和HTTPS证书的生成与安装
摘要 介绍linux系统下使用openssl生成https证书,并将证书安装在apache服务器上,最终实现通过https访问服务器。这个过程涉及到openssl生成自签名证书(适用于测试环境),修改apache配置,开放防火墙https端口…...
前端—Cursor编辑器
在当今快速发展的软件开发领域,效率和质量是衡量一个工具是否优秀的两个关键指标。今天,我要向大家推荐一款革命性的代码编辑器——Cursor,它集成了强大的AI功能,旨在提高开发者的编程效率。以下是Cursor编辑器的详细介绍和推荐理…...
【数据结构】【线性表】【练习】删除链表倒数第n个结点
目录 申明 题目 分析题目信息 解题思路 代码解析 技巧解析:创建虚拟头结点 时间复杂度分析 思考:能否只用一趟扫描实现? 双指针 双指针解题思路 代码解析 申明 该题源自力扣题库19,文章内容(代码,…...
MySQL高级(四):索引
基础概念 什么是索引? 索引是一种数据结构,用于加速查询的过程。它类似于书本的目录,可以快速定位数据行。MySQL 索引主要是基于 B 树(也有其他类型如哈希索引、全文索引等)来实现的。 为什么使用索引? …...
hhdb数据库介绍(9-21)
计算节点参数说明 checkClusterBeforeDnSwitch 参数说明: PropertyValue参数值checkClusterBeforeDnSwitch是否可见否参数说明集群模式下触发数据节点高可用切换时,是否先判断集群所有成员正常再进行数据节点切换默认值falseReload是否生效是 参数设…...
React中组件通信的几种方式
在构建复杂的React应用时,组件之间的通信是至关重要的。从简单的父子组件通信到跨组件状态同步,不同组件之间的通信方式多种多样。 1. 父子组件通信 父子组件通信是 React 中最基本的通信方式之一。在这种模式下,数据是从父组件通过 props …...
python脚本实现csv中百度经纬度转84经纬度
数据准备 csv文件,带百度经纬度字段:bd09_x,bd09_y 目的 将百度经纬度转换为84经纬度,并在csv文件中添加两个字段:84_x,84_y python脚本 from ChangeCoordinate import ChangeCoordimport pandas as pd import numpy as npcoord = ChangeCoord()def bd09_to_wgs84...
syslog udp配置笔记
要将 /var/log/ 目录下的日志信息通过 UDP 发送到远程服务器,可以使用 rsyslog 的配置来实现。以下是详细步骤: 步骤 1:确保 rsyslog 已安装 如果 rsyslog 没有安装,请使用以下命令进行安装: 在 CentOS/RHEL: sudo yum install rsyslog在 Ubuntu/Debian: sudo apt-get i…...
Linux环境开启MongoDB的安全认证
文章目录 1. MongoDB安全认证简介1.1 访问控制1.2 角色1.3 权限 2. MongoDB中的常见角色3. MongoDB Shell3.1 下载MongoDB Shell3.2 通过MongoDB Shell连接MongoDB 4. 创建管理员用户5. 为具体的数据库创建用户6. 开启权限认证7. 重启MongoDB服务8. 连接MongoDB9. MongoDB数据库…...
django基于Python的农产品销售系统的设计与实现
摘 要 随着现代人们的快速发展,农产品销售系统已成为农产品的需求。该平台采用Python技术和django搭建系统框架,后台使用MySQL数据库进行信息管理;通过个人中心、用户管理、商家管理、产品类型管理、农产品管理、系统管理、订单管理等功能&a…...
linux复习5:C prog
编辑 缩排 为了使C源代码更加整洁易读,可以使用一些工具来自动格式化代码,例如cb(C程序美化器)、bcpp(C美化器)和indent等。 编译 编译并链接C文件 gcc hello.c -o hello 将 hello.c 编译并链接成可执行文…...
Go语言24小时极速学习教程(三)常见标准库用法
常见标准库 常见标准库即Go语言自带的库,这里的所有包都可以通过import直接引入,如果你觉得实在是不好用,那么请先保证你学会了标准库的基础上,再学一下Gookit,特别是其中的GoUtil,千万不要轻易自己去造轮…...
大数据环境下的高效数据清洗策略
大数据环境下的高效数据清洗策略 在当今这个信息爆炸的时代,大数据已成为企业决策和科学研究不可或缺的重要资源。然而,数据的海量性、多样性和复杂性也给数据处理带来了前所未有的挑战,其中数据清洗是确保数据质量和后续分析准确性的关键步…...
基于SpringBoot3+mybatis搭建的历史上的今天API接口服务 及 Mybatis 应该有个更好的方法来隐藏 Pojo 类中的字段
一、Mybatis有没有比较好的方法隐藏 Pojo 类中的字段 使用 Mybatis 时,为了实现通用的CURD,在定义实体类pojo时,会尽量将能用得上的数据库字段都定义到 pojo中,但是在查询的时候却有不一样的需求。mybatis的文档地址链接ÿ…...
Python 3 字符串
Python 3 字符串 字符串在Python中是一种基本的数据类型,用于存储文本数据。Python中的字符串是不可变的,这意味着一旦创建了一个字符串,就不能更改其内容。字符串可以用单引号()、双引号("ÿ…...
Android集成FCM(Firebace Cloud Messaging )
集成FCM官方文档 Firebace主页面 将 Firebase 添加到您的 Android 应用 1、进入Firebace页面,创建自己的项目 2、点击自己创建好的项目,在右侧选择Cloud Messaging 3、点击Android去创建 google-services.json 4、将下载的 google-services.json 文件…...
基于 RBF 神经网络辨识的单神经元 PID 模型参考自适应控制
这是一个基于 RBF 神经网络辨识 和 单神经元 PID 模型参考自适应控制 的系统框图,包含以下主要部分: RBF 神经网络模块:用于对系统进行辨识,输入误差 e(t)e(t)e(t) 和误差变化量 Δe(t)\Delta e(t)Δe(t),输出与系统特…...
2024年 Web3开发学习路线全指南
Web3是一个包含了很多领域的概念,不讨论币圈和链圈的划分,Web3包括有Defi、NFT、Game等基于区块链的Dapp应用的开发;也有VR、AR等追求视觉沉浸感的XR相关领域的开发;还有基于区块链底层架构或者协议的开发。 这篇文章给出的学习路…...
Ubuntu22.04LTS 部署前后端分离项目
一、安装mysql8.0 1. 安装mysql8.0 # 更新安装包管理工具 sudo apt-get update # 安装 mysql数据库,过程中的选项选择 y sudo apt-get install mysql-server # 启动mysql命令如下 (停止mysql的命令为:sudo service mysql stop࿰…...
「Mac玩转仓颉内测版23」基础篇3 - 深入理解整数类型
本篇将详细讲解Cangjie中的整数类型,探讨整数的定义、操作、表示范围、进制表示、类型转换及应用场景,帮助开发者在Cangjie中灵活运用整数类型构建程序逻辑。 关键词 有符号整数与无符号整数表示范围与溢出进制表示类型转换字面量与操作 一、整数类型概…...
渗透测试导学
渗透测试导学 渗透测试概念 渗透测试是干什么? 渗透测试的定义和目的:渗透测试是一种通过模拟恶意黑客的攻击方法,来评估计算机网络系统安全性能的评估方法。它的目的是通过识别安全问题,帮助了解当前的安全状况,从而…...
Django实现智能问答助手-基础配置
设置 Django 项目、创建应用、定义模型和视图、实现问答逻辑,并设计用户界面。下面是一步一步的简要说明: 目录: QnAAssistant/ # 项目目录 │ ├── QnAAssistant/ # 项目文件夹 │ ├── init.py # 空文件 │ ├── settings.py # 项目配…...
亚马逊商品详情API接口解析,Json数据示例返回
亚马逊的商品详情API接口(如Amazon Product Advertising API)允许开发者获取商品的详细信息,包括价格、描述、图片URL等。以下是一个示例的JSON数据返回结构,以及相应的解析说明。请注意,实际返回的数据结构可能会根据…...
git根据远程分支创建本地新分支
比如我当前本地仓库有4个 remote 仓库,我希望根据其中的一个 <remote>/<branch> 创建本地分支: 先使用 github fetch <remote> 拉取 <remote> 的分支信息,然后在 git checkout -b 创建新分支时使用 -t <remote>…...
Android U 多任务启动分屏——SystemUI流程(更新中)
前文 Android U 多任务启动分屏——Launcher流程(下分屏) 前文说到通过ISplitScreen接口跨进程调用到了SystemUI进程,我们继续分析分屏在systemui中的实现。 wmshell实现分屏 实现ISplitScreen接口 代码路径:frameworks/base/…...
使用SaaS化的Aurora应用快速搭建私人ChatGPT助手
使用SaaS化的Aurora应用快速搭建私人ChatGPT助手 简介: Aurora是一个带UI且免费的GPT私人聊天助手,可切换GPT-3.5,4,4o等常用版本。用户可通过部署Aurora,快速打造自己专属的AI助手。阿里云计算巢已将Aurora打包为SaaS…...
.NET 9与C# 13革新:新数据类型与语法糖深度解析
记录(Record)类型 使用方式: public record Person(string FirstName, string LastName); 适用场景:当需要创建不可变的数据结构,且希望自动生成 GetHashCode 和 Equals 方法时。不适用场景:当数据结构需…...
怎样做网站公司/2024很有可能再次封城吗
编写任何javascript程序我们要首先获得对象, jQuery选择器能彻底改变我们平时获取对象的方式, 可以获取几乎任何语意的对象, 比如"拥有title属性并且值中包含test的<a>元素", 完成这些工作只需要编写一个jQuery选择器字符串. 学习jQuery选择器是学习jQuery最重…...
便宜虚拟主机做网站备份/公司网站设计的内容有哪些
公司电脑监控软件怎么样?哪家好?目前,许多公司都需要配置电脑监控软件来监控公司电脑,尤其现在公司电脑监控软件在行业内是非常多的,功能也非常强大。超级眼公司电脑监控软件,在监控软件内,企业…...
中国人做代购的网站/西安网站推广
原文链接:http://click.aliyun.com/m/13858/ 免费开通大数据服务:https://www.aliyun.com/product/odps目前人人都在谈大数据,谈DT时代,但是,大数据是什么,每个人都有自己的一个看法,好比盲人摸象ÿ…...
网站平台建设步骤/搜索seo优化托管
前言最近部门内抛出了一个问题,应用启动很慢、卡图标?主要表现在中低端机型中。究其这个问题,由于对性能优化比较感兴趣,借了个低端机和一个中端机来一看究竟,对同一应用分别测了下它在中低端机的启动时间,…...
wordpress反应很慢/济南计算机培训机构哪个最好
方法一: 选择添加——现有项,将排除的文件添加进来。 方法二: 在解决方案资源管理器上方有一排小按钮,找到那个显示所有文件,点击后,将显示你被排除的文件,然后再在这个文件上点击右键ÿ…...
wordpress 查看url/百度手游排行榜
【题目】方阵填数:在一个 N*N的方阵中,填入 1,2..... N*N个数,并要求构成如下格式: 图例:10 11 12 19 16 13 28 15 14 37 6 5 4【上手】观察图例,不难看出这是一个螺旋矩阵,下面是色…...