首页 > 其他分享 >【Swift底层进阶--018:高阶函数】

【Swift底层进阶--018:高阶函数】

时间:2022-12-10 16:37:20浏览次数:50  
标签:map 进阶 -- transform element let result Swift 函数

​Swift​​​是一门面向协议的语言,开发中我们已经充分享受到面向协议编程的便利,但​​Swift​​​相比​​OC​​还有一个更重要的优势,那就是对函数式编程提供了强大的支持。

其中​​Swift​​提供的高阶函数,常常用来作用于​​Array​​、​​Set​​、​​Dictionary​​中的每一个元素,它的本质也是函数,具有以下有两个特点:

  • 接受函数或者是闭包作为参数
  • 返回值是一个函数或者是闭包
map函数

​map​​函数作用于​​Collection​​中的每一个元素,然后返回一个新的​​Collection​

假设一个​​String​​类型的​​Array​​,要求将集合中的每一个元素都转为小写。常规代码会这样写:


let strings = ["HANK", "CAT", "Kody", "COOCI"]
var newStrings = [String]()

for ele in strings{
newStrings.append(ele.lowercased())
}

还可以使用​​map​​函数替代常规写法:


let strings = ["HANK", "CAT", "Kody", "COOCI"]
var newStrings = strings.map{ $0.lowercased() }
print(newStrings)

//输出以下内容
//["hank", "cat", "kody", "cooci"]
  • ​map​​函数可以对数组中的每一个元素做一次处理,如同遍历的作用
  • ​map​​函数接受一个闭包作为参数, 然后它会遍历整个数组,并对数组中每一个元素执行闭包中定义的操作。 相当于对数组中的所有元素做了一个映射
  • ​map​​函数可以对一个集合类型的所有元素做一个映射操作
  • ​map​​函数不会修改实例值, 而是新建一个拷贝

查看​​map​​函数的定义:


public func map<T>(_ transform: (Output) -> T) -> Just<T>

在源码中打开​​Sequence.swift​​文件,找到​​map​​函数的定义,它其实是​​Sequence​​协议的扩展


/// - Parameter transform: A mapping closure. `transform` accepts an
/// element of this sequence as its parameter and returns a transformed
/// value of the same or of a different type.
/// - Returns: An array containing the transformed elements of this
/// sequence.
///
/// - Complexity: O(*n*), where *n* is the length of the sequence.
@inlinable
public func map<T>(
_ transform: (Element) throws -> T
) rethrows -> [T] {
let initialCapacity = underestimatedCount
var result = ContiguousArray<T>()
result.reserveCapacity(initialCapacity)

var iterator = self.makeIterator()

// Add elements up to the initial capacity without checking for regrowth.
for _ in 0..<initialCapacity {
result.append(try transform(iterator.next()!))
}
// Add remaining elements, if any.
while let element = iterator.next() {
result.append(try transform(element))
}
return Array(result)
}

上述源码,可以看出​​map​​函数本质是创建新的数组,对集合内的每个元素进行​​transform​​操作(闭包表达式),然后返回新数组

flatMap函数

先来看一下​​flatMap​​函数的定义:


public func flatMap<ElementOfResult>(_ transform: (Element) throws -> ElementOfResult?) rethrows -> [ElementOfResult]

打开​​SequenceAlgorithms.swift​​文件,找到​​flatMap​​函数的定义:


/// - Parameter transform: A closure that accepts an element of this
/// sequence as its argument and returns a sequence or collection.
/// - Returns: The resulting flattened array.
///
/// - Complexity: O(*m* + *n*), where *n* is the length of this sequence
/// and *m* is the length of the result.
@inlinable
public func flatMap<SegmentOfResult: Sequence>(
_ transform: (Element) throws -> SegmentOfResult
) rethrows -> [SegmentOfResult.Element] {
var result: [SegmentOfResult.Element] = []
for element in self {
result.append(contentsOf: try transform(element))
}
return result
}

上述源码,​​flatMap​​函数中的闭包参数,同样是​​Sequence​​类型,但其返回类型为​​SegmentOfResult​

在函数体的泛型定义中,​​SegmentOfResult​​的类型其实就是​​Sequence​​。 而​​flatMap​​函数返回的类型是​​SegmentOfResult.Element​​的数组

从函数的返回值来看,与​​map​​函数的区别在于​​flatMap​​函数会将​​Sequence​​中的元素进行“压平”,返回的类型会是​​Sequence​​中元素类型的数组,而​​map​​函数返回的是闭包返回类型​​T​​的数组

相比较​​map​​函数来说,​​flatMap​​函数最主要的两个作用一个是“压平”,一个是过滤​​nil​​值

案例1

二维数组“压平”


let nums = [[1, 2, 3], [4, 5, 6]]

var result1 = nums.map{$0}
var result2 = nums.flatMap{$0}

print("map:\(result1)")
print("flatMap:\(result2)")

//输出以下内容
//map:[[1, 2, 3], [4, 5, 6]]
//flatMap:[1, 2, 3, 4, 5, 6]

上述代码,使用​​map​​函数输出的还是二维数组,但使用​​flatMap​​函数变成一维数组

案例2

过滤​​nil​​值


let strings = ["HANK", "CAT", "Kody", "COOCI", nil]

var result1 = strings.map{$0}
var result2 = strings.flatMap{$0}

print("map:\(result1)")
print("flatMap:\(result2)")

//输出以下内容
//map:[Optional("HANK"), Optional("CAT"), Optional("Kody"), Optional("COOCI"), nil]
//flatMap:["HANK", "CAT", "Kody", "COOCI"]

上述代码,使用​​map​​函数,数组内元素变为​​Optional​​类型,同时​​nil​​值也被保留。使用​​flatMap​​函数,会把数组内元素进行​​Optional​​解包,并且过滤​​nil​​值


let number: String? = String(20)
let restult = number.map{Int($0)}

上述代码,​​number​​为​​String​​可选类型,使用​​map​​函数将其转为​​Int​​类型,此时​​restult​​类型变为两层可选类型,使用时需要解包两次




【Swift底层进阶--018:高阶函数】_数组






let number: String? = String(20)
let restult = number.flatMap{Int($0)}

同样的代码,使用​​flatMap​​函数,​​restult​​依然保持为可选类型




【Swift底层进阶--018:高阶函数】_IOS_02





打开​​Optional.swift​​文件,找到​​map​​函数的定义:


/// - Parameter transform: A closure that takes the unwrapped value
/// of the instance.
/// - Returns: The result of the given closure. If this instance is `nil`,
/// returns `nil`.
@inlinable
public func map<U>(
_ transform: (Wrapped) throws -> U
) rethrows -> U? {
switch self {
case .some(let y):
return .some(try transform(y))
case .none:
return .none
}
}

上述源码,当进入​​case .some​​的代码分支,返回时又进行了​​.some()​​的调用,增加了一层可选

找到​​flatMap​​函数的定义:


/// - Parameter transform: A closure that takes the unwrapped value
/// of the instance.
/// - Returns: The result of the given closure. If this instance is `nil`,
/// returns `nil`.
@inlinable
public func flatMap<U>(
_ transform: (Wrapped) throws -> U?
) rethrows -> U? {
switch self {
case .some(let y):
return try transform(y)
case .none:
return .none
}
}

上述源码,当进入​​case .some​​的代码分支,直接进行​​transform​​操作,将结果返回

  • ​flatMap​​函数依然会遍历数组的元素,并对这些元素执行闭包中定义的操作
  • 与​​map​​函数不同的是,它对最终的结果进行了所谓的“压平”操作。多维数组​​flatMap​​之后,变成一维数组
  • ​flatMap​​函数返回后,数组的元素会过滤​​nil​​值,同时它会把​​Optional​​解包
compactMap函数

序列可选类型,在​​Swift 4.1​​之后,应该将​​flatMap​​替换为​​compactMap​




【Swift底层进阶--018:高阶函数】_数组_03





打开​​SequenceAlgorithms.swift​​文件,找到​​compactMap​​函数的定义:


/// - Parameter transform: A closure that accepts an element of this
/// sequence as its argument and returns an optional value.
/// - Returns: An array of the non-`nil` results of calling `transform`
/// with each element of the sequence.
///
/// - Complexity: O(*m* + *n*), where *n* is the length of this sequence
/// and *m* is the length of the result.
@inlinable // protocol-only
public func compactMap<ElementOfResult>(
_ transform: (Element) throws -> ElementOfResult?
) rethrows -> [ElementOfResult] {
return try _compactMap(transform)
}

// The implementation of flatMap accepting a closure with an optional result.
// Factored out into a separate functions in order to be used in multiple
// overloads.
@inlinable // protocol-only
@inline(__always)
public func _compactMap<ElementOfResult>(
_ transform: (Element) throws -> ElementOfResult?
) rethrows -> [ElementOfResult] {
var result: [ElementOfResult] = []
for element in self {
if let newElement = try transform(element) {
result.append(newElement)
}
}
return result
}
}

上述源码,在​​_compactMap​​方法内,遍历元素过程中做了可选值绑定操作,然后进行​​append​


let strings = ["HANK", "CAT", "Kody", "COOCI", nil]
var result = strings.compactMap{$0}
print(result)

//输出以下内容
//["HANK", "CAT", "Kody", "COOCI"]

上述代码,使用​​compactMap​​函数将​​nil​​值过滤

  • 当转换闭包返回可选值并且期望得到的结果为非可选值的序列时,使用​​compactMap​​函数
  • 当对于序列中元素,转换闭包返回的是序列或者集合时,而期望得到的结果是一维数组,使用​​flatMap​​函数
filter函数

​filter​​函数用于过滤元素,筛选出集合中满足某种条件的元素


let nums = [1, 2, 3, 4, 5]
let result = nums.filter{ $0 % 2 != 0 }
print(result)

//输出以下结果:
//[1, 3, 5]

上述代码,使用​​filter函数​​找到数组元素中的奇数

打开​​Sequence.swift​​文件,找到​​filter​​函数的定义:


/// - Parameter isIncluded: A closure that takes an element of the
/// sequence as its argument and returns a Boolean value indicating
/// whether the element should be included in the returned array.
/// - Returns: An array of the elements that `isIncluded` allowed.
///
/// - Complexity: O(*n*), where *n* is the length of the sequence.
@inlinable
public __consuming func filter(
_ isIncluded: (Element) throws -> Bool
) rethrows -> [Element] {
return try _filter(isIncluded)
}

@_transparent
public func _filter(
_ isIncluded: (Element) throws -> Bool
) rethrows -> [Element] {

var result = ContiguousArray<Element>()

var iterator = self.makeIterator()

while let element = iterator.next() {
if try isIncluded(element) {
result.append(element)
}
}

return Array(result)
}
  • ​filter​​函数将闭包表达式作为参数
  • 调用​​ContiguousArray<Element>()​​声明一个空集合
  • 使用​​self.makeIterator()​​生成一个迭代器
  • 通过​​while​​遍历元素
  • 将​​isIncluded​​(闭包表达式)作为判断条件,将符合条件的元素加入到集合中
  • 返回新数组
forEach函数

对于集合类型的元素,不必每次都通过​​for​​循环来做遍历,​​Sequence​​中同样提供了高阶函数以供使用:


let nums = [1, 2, 3, 4, 5]

nums.forEach {
print($0)
}

上述代码,通过​​forEach​​函数遍历数组元素进行打印

打开​​Sequence.swift​​文件,找到​​forEach​​函数的定义:


/// Using the `forEach` method is distinct from a `for`-`in` loop in two
/// important ways:
///
/// 1. You cannot use a `break` or `continue` statement to exit the current
/// call of the `body` closure or skip subsequent calls.
/// 2. Using the `return` statement in the `body` closure will exit only from
/// the current call to `body`, not from any outer scope, and won't skip
/// subsequent calls.
///
/// - Parameter body: A closure that takes an element of the sequence as a
/// parameter.
@_semantics("sequence.forEach")
@inlinable
public func forEach(
_ body: (Element) throws -> Void
) rethrows {
for element in self {
try body(element)
}
}
}

上述源码,​​forEach​​函数的本质还是使用​​for...in​​循环,执行闭包表达式

如果想获取当前元素的​​index​​,可以使用​​enumerated​​函数




【Swift底层进阶--018:高阶函数】_数组_04






let nums = [1, 2, 3, 4, 5]

nums.enumerated().forEach {
print("index:\($0),emelent:\($1)")
}

//输出以下结果:
//index:0,emelent:1
//index:1,emelent:2
//index:2,emelent:3
//index:3,emelent:4
//index:4,emelent:5

上述代码,可以同时输出​​index​​和​​emelent​

找到​​emelent​​函数的定义,返回一个​​EnumeratedSequence​​类型


@inlinable public func enumerated() -> EnumeratedSequence<Array<Element>>

打开​​Algorithm.swift​​文件,找到​​EnumeratedSequence​​定义:


@frozen
public struct EnumeratedSequence<Base: Sequence> {
@usableFromInline
internal var _base: Base

/// Construct from a `Base` sequence.
@inlinable
internal init(_base: Base) {
self._base = _base
}
}

​EnumeratedSequence​​是一个接收​​Sequence​​类型的结构体


extension EnumeratedSequence {
@frozen
public struct Iterator {
@usableFromInline
internal var _base: Base.Iterator
@usableFromInline
internal var _count: Int

/// Construct from a `Base` iterator.
@inlinable
internal init(_base: Base.Iterator) {
self._base = _base
self._count = 0
}
}
}

​Iterator​​是​​EnumeratedSequence​​内部用到的迭代器,​​_count​​就是​​index​


extension EnumeratedSequence.Iterator: IteratorProtocol, Sequence {
/// The type of element returned by `next()`.
public typealias Element = (offset: Int, element: Base.Element)

/// Advances to the next element and returns it, or `nil` if no next element
/// exists.
///
/// Once `nil` has been returned, all subsequent calls return `nil`.
@inlinable
public mutating func next() -> Element? {
guard let b = _base.next() else { return nil }
let result = (offset: _count, element: b)
_count += 1
return result
}
}

​next​​用来生成元素,返回一个元组类型。所以我们可以使用​​$0​​获取​​index​​,使用​​$1​​获取​​emelent​

reduce函数
  • ​reduce​​函数可以对数组的元素进行计算
  • ​reduce​​函数可以将数组元素组合计算为一个值,并且会接受一个初始值,这个初始值的类型可以和数组元素类型不同
  • 将数组元素合并成字符串,元素之间可以指定分隔符号


let nums = [1, 2, 3, 4, 5]
let result = nums.reduce(10, +)
print(result)

//输出以下结果:
//25

上述代码,使用​​reduce​​函数将数组内元素和初始值​​10​​,通过闭包表达式进行求和

打开​​SequenceAlgorithms.swift​​文件,找到​​reduce​​函数的定义:


/// - Parameters:
/// - initialResult: The value to use as the initial accumulating value.
/// `initialResult` is passed to `nextPartialResult` the first time the
/// closure is executed.
/// - nextPartialResult: A closure that combines an accumulating value and
/// an element of the sequence into a new accumulating value, to be used
/// in the next call of the `nextPartialResult` closure or returned to
/// the caller.
/// - Returns: The final accumulated value. If the sequence has no elements,
/// the result is `initialResult`.
///
/// - Complexity: O(*n*), where *n* is the length of the sequence.
@inlinable
public func reduce<Result>(
_ initialResult: Result,
_ nextPartialResult:
(_ partialResult: Result, Element) throws -> Result
) rethrows -> Result {
var accumulator = initialResult
for element in self {
accumulator = try nextPartialResult(accumulator, element)
}
return accumulator
}
  • ​initialResult​​:初始值
  • ​nextPartialResult​​:闭包表达式
  • ​accumulator​​:累加器

遍历集合,将累加器和元素传入闭包表达式进行指定操作,将结果重新赋值给累加器,最后将累加器返回

案例1

对集合内每个元素进行​​*2​​操作


func customMap(collection: [Int], transform: (Int) -> Int) -> [Int]{
return collection.reduce([Int]()){
var arr: [Int] = $0
arr.append(transform($1))
return arr
}
}

let nums = [1, 2, 3, 4, 5]
let result = customMap(collection: nums){
$0 * 2
}

print(result)

//输出以下结果:
//[2, 4, 6, 8, 10]

上述代码,定义​​customMap​​方法

  • 方法内部使用​​reduce​​函数,初始值为空数组
  • 闭包表达式内部将​​$0​​空数组赋值给​​arr​​变量
  • 将​​$1​​元素传入​​transform​​闭包表达式
  • 将执行结果​​append​​到​​arr​​数组并进行返回

也可以通过​​reduce​​函数直接实现上述需求,由于传入的集合是可变数组,需要使用​​reduce(into:)​​方法,否则编译报错




【Swift底层进阶--018:高阶函数】_swift_05


编译报错




let nums = [1, 2, 3, 4, 5]

let result = nums.reduce(into: [Int]()){
$0.append($1 * 2)
}

print(result)

//输出以下结果:
//[2, 4, 6, 8, 10]

上述代码,使用​​reduce(into:)​​方法,也可以实现同样的效果

案例2

找出数组当中的最大值


let result = [1, 2, 3, 4, 5].reduce(0){
return $0 < $1 ? $1 : $0
}

print(result)

//输出以下结果:
//5

上述代码,要想找到最大值,一定会进行比较,这里的逻辑是通过累加器和元素进行比较

  • 累加器初始传入​​0​
  • 闭包表达式内,使用累加器和元素值比较
  • 如果累加器小于元素值,将元素值赋值给累加器
  • 循环往复,最终返回的累加器就是数组内元素的最大值
案例3

找到数组内奇数,再找到距离它最近的​​2​​的​​n​​次方数,最后计算出总和


extension FixedWidthInteger {
@inlinable
func nextPowerOf2() -> Self {
guard self != 0 else {
return 1
}
return 1 << (Self.bitWidth - (self - 1).leadingZeroBitCount)
}
}

let result = [1, 2, 3, 4, 5].filter{
$0 % 2 != 0
}.map{
$0.nextPowerOf2()
}.reduce(0){
$0 + $1
}

print(result)

//输出以下结果:
//13
  • 使用​​filter​​方法筛选出数组内奇数
  • 使用​​map​​方法将数组内元素依次通过​​nextPowerOf2​​方法,找到距离元素值最近的​​2​​的​​n​​次方数
  • 使用​​reduce​​方法求和
案例4

逆序数组


let result = [1, 2, 3, 4, 5].reduce([Int]()){
return [$1] + $0
}

print(result)

//输出以下结果:
//[5, 4, 3, 2, 1]
  • 累加器初始传入空数组
  • 将元素包装成数组和累加器的数组相加,等同于两个数组元素合并
  • 将合并后的数组赋值给累加器,直到所有元素合并完
LazySequence

假设我们有一个非常庞大的数组,想要通过​​map​​函数对每一个元素进行​​*2​​,这将是一个非常耗时的操作


let numbers = Array(1...100000)
let mapNumbers = numbers.map{ $0 * 2 }

合理的逻辑,应该使用懒加载,在元素被访问的时候进行​​*2​​操作。但这样做还能使用​​map​​函数吗?

答案当然是可以的,​​Swift​​提供了⼀个​​lazy​​关键字,它能实现这样的效果:


let numbers = Array(1...100000)
let mapNumbers = numbers.lazy.map{ $0 * 2 }

print(mapNumbers)

上述代码,直接输出​​mapNumbers​​,可以看到里面的元素没有发生任何变化




【Swift底层进阶--018:高阶函数】_sed_06






let numbers = Array(1...100000)
let mapNumbers = numbers.lazy.map{ $0 * 2 }

print(mapNumbers[0])
print(mapNumbers[1])
print(mapNumbers[2])

//输出以下结果:
//2
//4
//6

上述代码,当数组内指定元素被访问,这时该元素才会进行​​*2​​操作

通过上面的案例来看,当使⽤​​Lazy​​关键字后,得到的​​mapNumbers​​保留的还是原来的数据,只不过在访问指定元素时,才会执⾏对应的闭包操作,产⽣新值给我们

当使用​​lazy​​关键字后,返回的是一个​​LazySequence​​的结构体




【Swift底层进阶--018:高阶函数】_sed_07





查看​​lazy​​的定义:


@inlinable public var lazy: LazySequence<Array<Element>> { get }


打开​​LazySequence.swift​​文件,找到​​LazySequenceProtocol​​协议的定义:


public protocol LazySequenceProtocol: Sequence {
/// A `Sequence` that can contain the same elements as this one,
/// possibly with a simpler type.
///
/// - See also: `elements`
associatedtype Elements: Sequence = Self where Elements.Element == Element

/// A sequence containing the same elements as this one, possibly with
/// a simpler type.
///
/// When implementing lazy operations, wrapping `elements` instead
/// of `self` can prevent result types from growing an extra
/// `LazySequence` layer. For example,
///
/// _prext_ example needed
///
/// Note: this property need not be implemented by conforming types,
/// it has a default implementation in a protocol extension that
/// just returns `self`.
var elements: Elements { get }
}

​LazySequenceProtocol​​协议遵循了​​Sequence​​协议

找到​​lazy​​的定义:


extension Sequence {
/// A sequence containing the same elements as this sequence,
/// but on which some operations, such as `map` and `filter`, are
/// implemented lazily.
@inlinable // protocol-only
public var lazy: LazySequence<Self> {
return LazySequence(_base: self)
}
}

​lazy​​是一个计算属性,返回一个​​LazySequence​​对象


@frozen // lazy-performance
public struct LazySequence<Base: Sequence> {
@usableFromInline
internal var _base: Base

/// Creates a sequence that has the same elements as `base`, but on
/// which some operations such as `map` and `filter` are implemented
/// lazily.
@inlinable // lazy-performance
internal init(_base: Base) {
self._base = _base
}
}

​LazySequence​​初始化的时候,保留了当前的集合


extension LazySequence: Sequence {
public typealias Element = Base.Element
public typealias Iterator = Base.Iterator

@inlinable
public __consuming func makeIterator() -> Iterator {
return _base.makeIterator()
}

@inlinable // lazy-performance
public var underestimatedCount: Int {
return _base.underestimatedCount
}

@inlinable // lazy-performance
@discardableResult
public __consuming func _copyContents(
initializing buf: UnsafeMutableBufferPointer<Element>
) -> (Iterator, UnsafeMutableBufferPointer<Element>.Index) {
return _base._copyContents(initializing: buf)
}

@inlinable // lazy-performance
public func _customContainsEquatableElement(_ element: Element) -> Bool? {
return _base._customContainsEquatableElement(element)
}

@inlinable // generic-performance
public __consuming func _copyToContiguousArray() -> ContiguousArray<Element> {
return _base._copyToContiguousArray()
}
}
  • ​LazySequence​​扩展,遵循​​Sequence​​协议
  • ​makeIterator()​​方法创建迭代器

打开​​Map.swift​​文件,找到在​​LazySequenceProtocol​​扩展中实现的​​map​​函数


extension LazySequenceProtocol {
/// Returns a `LazyMapSequence` over this `Sequence`. The elements of
/// the result are computed lazily, each time they are read, by
/// calling `transform` function on a base element.
@inlinable
public func map<U>(
_ transform: @escaping (Element) -> U
) -> LazyMapSequence<Elements, U> {
return LazyMapSequence(_base: elements, transform: transform)
}
}
  • ​LazySequenceProtocol​​扩展,实现​​map​​函数
  • 返回一个​​LazyMapSequence​​对象


/// A `Sequence` whose elements consist of those in a `Base`
/// `Sequence` passed through a transform function returning `Element`.
/// These elements are computed lazily, each time they're read, by
/// calling the transform function on a base element.
@frozen
public struct LazyMapSequence<Base: Sequence, Element> {

public typealias Elements = LazyMapSequence

@usableFromInline
internal var _base: Base
@usableFromInline
internal let _transform: (Base.Element) -> Element

/// Creates an instance with elements `transform(x)` for each element
/// `x` of base.
@inlinable
internal init(_base: Base, transform: @escaping (Base.Element) -> Element) {
self._base = _base
self._transform = transform
}
}

​LazyMapSequence​​初始化的时候,保存了当前集合和​​transform​​闭包表达式


extension LazyMapSequence.Iterator: IteratorProtocol, Sequence {
/// Advances to the next element and returns it, or `nil` if no next element
/// exists.
///
/// Once `nil` has been returned, all subsequent calls return `nil`.
///
/// - Precondition: `next()` has not been applied to a copy of `self`
/// since the copy was made.
@inlinable
public mutating func next() -> Element? {
return _base.next().map(_transform)
}
}

当访问指定元素时,会调用​​next()​​方法,然后对元素进行​​transform​​操作

所以​​Lazy​​的本质,其实就是保存当前集合和对应的操作,然后在访问具体元素的时候,执⾏对应的操作



标签:map,进阶,--,transform,element,let,result,Swift,函数
From: https://blog.51cto.com/u_13146445/5927772

相关文章

  • 数据库设计
    数据库设计表关系一对一如:用户和用户详情一对一的关系多用于表的拆分,讲一个实体经常使用的子端但放一张表,不经常使用的子端放另一张表,用于提升查询性能实现方......
  • postgresql FRONTEND、EXEC_BACKEND宏定义的作用
    FONTEND宏主要用于标记某些可能会在libpq客户端使用的场景,虽然他们主要用于服务端。如下:/**Althoughthisheaderfileisnominallybackend-only,certainfrontend*p......
  • powershell简介
    powershell简介PowerShell是一种跨平台的任务自动化解决方案,由命令行shell、脚本语言和配置管理框架组成。PowerShell可以在Windows、Linux和macOS上运行。注释......
  • lightdb enterrpise postgres并行执行及限制
    有几个参数控制并行执行的行为zjh@postgres=#show%parallel%;name|setting|description......
  • postgresql/lightdb分区技术及其优化
    ​​PostgreSQL​​ 10开始,实现了原生表分区,算是真正意义上进入了支持分区的数据库的圈子。​​11​​​实现了大量的功能如支持更新分区键、默认分区、自动创建分......
  • ifdown和ifup命令
    ifdown命令ifdown命令用于禁用指定的网络接口。该命令会去读取/etc/sysconfig/network-scripts/目录下的相关网络接口的配置文件,并根据配置文件的内容来关闭该网络接口。......
  • lightdb/postgresql----JSON/JSONB类型、函数及全文检索的支持以及性能表现
    createtabletest_ft(idint4,arryVARCHAR[],content1jsonb,bodytext);insertintotest_ftvalues(1,ARRAY['x','y'],'{"guid":"9c36adc1-7fb5-4d5b-83b4-90356a4......
  • k8s节点磁盘满了,无法调度的解决方案
     在fat-k8s-worker13节点上操作1、先清理磁盘垃圾文件2、删除Exited状态的容器(删除的过程中遇到报错没关系,只要执行一次就好)dockerrm-f$(dockerps-a|grep'E......
  • lightdb for pg查看锁
    selectd.datname,c.relname,c.reltype,a.*frompg_locksa,pg_catalog.pg_databased,pg_catalog.pg_classcwhered.oid=a.databaseandc.oid=a.relation;当前数......
  • flutter tabbar切换监听及索引获取
    参考:https://www.jianshu.com/p/f1347e658fa6 定义lateTabController_controller; 在 voidinitState()中监听 tabController=TabController(leng......