Immutable.js API 简介

news2024/11/25 23:25:54
  • Immutable-js
    • 这个库的实现是深拷贝还是浅拷贝?
    • immutable 来源
    • immutable.js三大特性:
      • 持久化数据结构
      • 结构共享
      • 惰性操作
    • Immutable.js 的几种数据类型
  • immutable 使用
    • 使用 npm 安装 immutable:
  • 常用API介绍
    • Map
    • List
    • List.isList() 和 Map.isMap()
    • set() / setIn()
    • get() / getIn()
    • size
    • includes()
    • first() 、 last()
    • is()
    • merge , concat
    • concat()
    • updateIn() 回调函数更新 – 用法参考setIn()
    • toJS()
    • fromJS()
    • 总结:增删改查(所有操作都会返回新的值,不会修改原来值)
  • Immutable-js 优缺点
    • 优点:
      • 降低mutable带来的复杂度
      • 节省内存
      • 历史追溯性(时间旅行)
    • 缺点:
      • 需要重新学习api
      • 资源包大小增加(源码5000行左右)
      • 容易与原生对象混淆:由于api与原生不同,混用的话容易出错。

Immutable-js

Immutable.js,

github地址:https://github.com/immutable-js/immutable-js

每次修改一个 Immutable 对象时都会创建一个新的不可变的对象,在新对象上操作并不会影响到原对象的数据

这个库的实现是深拷贝还是浅拷贝?

Immutable ([ɪˈmjuːtəbl] 不变的;不可变的;不能变的) 是 Facebook 开发的不可变数据集合

不可变数据一旦创建就不能被修改,使得应用开发更简单,允许使用函数式编程技术,比如惰性评估。

Immutable JS 提供一个惰性 Sequence,允许高效的队列方法链,类似 map 和 filter ,不用创建中间代表。

immutable 通过惰性队列哈希映射提供 Sequence, Range, Repeat, Map, OrderedMap, Set 和一个稀疏 Vector。

immutable 来源

Immutable.js出自Facebook,是最流行的不可变数据结构的实现之一。

它实现了**完全的 持久化 数据结构**,通过使用像tries这样的先进技术来实现结构共享。

所有的更新操作都会返回新的值,但是在内部结构是共享的,来减少内存占用(和垃圾回收的失效)。

immutable.js三大特性:

  • Persistent data structure (持久化数据结构)
  • structural sharing (结构共享)
  • support lazy operation (惰性操作)

持久化数据结构

这里说的持久化是用来描述一种数据结构

指一个数据,在被修改时,仍然能够保持修改前的状态,即不可变类型

immutable.js提供了十余种不可变的类型(List,Map,Set,Seq,Collection,Range等)

结构共享

Immutable使用先进的tries(字典树)技术实现结构共享来解决性能问题.

当我们对一个Immutable对象进行操作的时候

ImmutableJS会只clone该节点以及它的祖先节点,其他保持不变,这样可以共享相同的部分,大大提高性能。

惰性操作

const oddSquares = Immutable.seq.of(1, 2, 3, 4, 5, 6, 7, 8)
  .filter(item => {
    console.log('immutable对象的filter执行');
    return item % 2;
  })
  .map(x => x * x);

console.log(oddSquares.get(1)); // 9

const jsSquares = [1, 2, 3, 4, 5, 6, 7, 8]
  .filter(item => {
    console.log('原生数组的filter执行');
    return item % 2;
  })
  .map(x => x * x);

console.log(jsSquares[1]); // 9

用seq创建的对象,其实代码块没有被执行,只是被声明了,

代码在get(1)的时候才会实际被执行,取到index=1的数之后,后面的就不会再执行了,

所以在filter时,第三次就取到了要的数,从4-8都不会再执行。

如果在实际业务中,数据量非常大,一个array的长度是几百,要操作这样一个array,如果应用惰性操作的特性,会节省非常多的性能。

Immutable.js 的几种数据类型

  • List: 有序索引集,类似JavaScript中的Array。
  • Map: 无序索引集,类似JavaScript中的Object。
  • OrderedMap: 有序的Map,根据数据的set()进行排序。
  • Set: 没有重复值的集合
  • OrderedSet: 有序的Set,根据数据的add进行排序。
  • Stack: 有序集合,支持使用unshift()和shift()添加和删除。
  • Record: 一个用于生成Record实例的类。类似于JavaScript的Object,但是只接收特定字符串为key,具有默认值。
  • Seq: 序列,但是可能不能由具体的数据结构支持。
  • Collection: 是构建所有数据结构的基类,不可以直接构建。

用的最多就是ListMap这两种数据类型。

immutable 使用

使用 npm 安装 immutable:

npm install immutable
```js 

每个模块都要包括:

```js 
var Immutable = require('immutable'); 
var map = Immutable.Map({a:1, b:2, c:3});

常用API介绍

Map

Map(): 原生object转Map对象 (只会转换第一层,注意和fromJS区别)

作用:用来创建一个新的Map对象

代码实现

var obj = { name: 'demo', age: 100 }
var oldImmutableObj = Map(obj)
console.log(oldImmutableObj)

//Map
Immutable.Map(); // 空Map
Immutable.Map({ a: '1', b: '2' });

List

List(): 原生array转List对象 (只会转换第一层,注意和fromJS区别)

作用:用来创建一个新的List对象

代码实现

const { List } = require('immutable'); 
const list1 = List([ 1, 2 ]); 
const list2 = list1.push(3, 4, 5); 
const list3 = list2.unshift(0); 
const list4 = list1.concat(list2, list3); 

assert.equal(list1.size, 2); 
assert.equal(list2.size, 5); 
assert.equal(list3.size, 6); 
assert.equal(list4.size, 13);
assert.equal(list4.get(0), 1);   

push, set, unshift or splice 都可以直接用,返回一个新的immutable对象

List.isList() 和 Map.isMap()

作用:判断一个数据结构是不是List/Map类型

用法

List.isList([]); // false
List.isList(List()); // true

Map.isMap({}) // false
Map.isMap(Map()) // true

set() / setIn()

set()修改immutalble的值:设置第一层key、index的值

用法

var NewImmutableObj = oldImmutableObj.set('name' , 'demo2')

const originalList = List([ 0 ]);
// List [ 0 ]
originalList.set(1, 1);
// List [ 0, 1 ]
originalList.set(0, 'overwritten');
// List [ "overwritten" ]
originalList.set(2, 2);
// List [ 0, undefined, 2 ]

const originalMap = Map()
const newerMap = originalMap.set('key', 'value')
const newestMap = newerMap.set('key', 'newer value')

List在使用的时候,将index为number值设置为value。

Map在使用的时候,将key的值设置为value。

在List中使用时,若传入的number为负数,则将index为size+index的值设置为value,
例,若传入-1,则将size-1的值设为value。

若传入的number的值超过了List的长度,则将List自动补全为传入的number的值,将number设置为value,其余用undefined补全。

注:跟js中不同,List中不存在空位,[,],List中若没有值,则为undefined。

setIn()修改immutalble的值:设置深层结构中某属性的值

用法

const originalMap = Map({
  subObject: Map({
    subKey: 'subvalue',
    subSubObject: Map({
      subSubKey: 'subSubValue'
    })
  })
})

const newMap = originalMap.setIn(['subObject', 'subKey'], 'ha ha!')
// Map {
//   "subObject": Map {
//     "subKey": "ha ha!",
//     "subSubObject": Map { "subSubKey": "subSubValue" }
//   }
// }
const newerMap = originalMap.setIn(
  ['subObject', 'subSubObject', 'subSubKey'],
  'ha ha ha!'
)

// Map {
//   "subObject": Map {
//     "subKey": "subvalue",
//     "subSubObject": Map { "subSubKey": "ha ha ha!" }
//   }
// }

用法与set()一样,只是第一个参数是一个数组代表要设置的属性所在的位置

get() / getIn()

get()获取immutalble 获取一级属性的值

//获取List索引的元素
ImmutableData.get(0);

// 获取Map对应key的value
ImmutableData.get('a');

oldImmuObj.get("name")
newImmuObj.get("name")

案例

import React, { Component } from 'react'
import { Map } from 'immutable' 

export default class App extends Component {

  state = {
    info: Map({
      name: 'demo',
      age: 100
    })
  }
  render() {
    return (
      <div>  
      this.state.info.get('name') --   {this.state.info.get('name')} <br/>
      this.state.info.get('age') --   {this.state.info.get('age')} <br/>
      
      <button onClick={()=>{
        this.setState({
          info: this.state.info.set('name','32333').set('age', 1000)
        })
      }}>修改</button>
      </div>
    )
  }
}

getIn()获取immutalble 获取多级属性的值

// 获取嵌套数组中的数据
ImmutableData.getIn([1, 2]);

// 获取嵌套map的数据
ImmutableData.getIn(['a', 'b']); 

const { Map } = require('immutable'); 
const map1 = Map({ a: 1, b: 2, c: 3 }); 
const map2 = map1.set('b', 50);  
map1.get('b') + " vs. " + map2.get('b'); // 2 vs. 50

多重对象情况

import React, { Component } from 'react'
import { Map } from 'immutable'

export default class App extends Component { 
  state = {
    info: Map({
      name: 'demo',
      select: 'aa',
      fliter: Map({
        text: '',
        up: true,
        down: false
      })
    })
  }

  componentDidMount() {
    // console.log(this.state.info)
  }

  render() {
    return (
      <div>
        <button onClick={() => {
          this.setState({
            info: this.state.info.set('name', 'dsdsdd')
          })
        }}>change</button> <br />
        this.state.info.get('name') --   {this.state.info.get('name')} <br />
        <Child fliter={this.state.info.get('filter')}></Child
      </div>
    )
  }
}


class Child extends Component {
  shouldComponentUpdate(nextProps, nextState) {
    if (this.props.filter === nextProps.filter) { // 注意此处:判断是否变化
      return false
    }
    return true
  }

  render() {
    return (
      <div>Child -- {this.props.fliter}</div>
    )
  }

  componentDidUpdate() {
    console.log('componentDidUpdate')
  }
}

size

作用:属性,获取List/Map的长度,等同于ImmutableData.count();

用法

// 查看List或者map大小  
immutableData.size  

或者

immutableData.count()
```js 

### has() 、 hasIn()

**作用**:判断是否存在某一个key

**用法**: 

```js 
Immutable.fromJS([1,2,3,{a:4,b:5}]).has('0'); //true
Immutable.fromJS([1,2,3,{a:4,b:5}]).has('0'); //true
Immutable.fromJS([1,2,3,{a:4,b:5}]).hasIn([3,'b']) //true

includes()

作用:判断是否存在某一个value

用法

Immutable.fromJS([1,2,3,{a:4,b:5}]).includes(2); //true
Immutable.fromJS([1,2,3,{a:4,b:5}]).includes('2'); //false 不包含字符2
Immutable.fromJS([1,2,3,{a:4,b:5}]).includes(5); //false 
Immutable.fromJS([1,2,3,{a:4,b:5}]).includes({a:4,b:5}) //false
Immutable.fromJS([1,2,3,{a:4,b:5}]).includes(Immutable.fromJS({a:4,b:5})) //true

first() 、 last()

作用:用来获取第一个元素或者最后一个元素,若没有则返回undefined

代码

Immutable.fromJS([1,2,3,{a:4,b:5}]).first()//1
Immutable.fromJS([1,2,3,{a:4,b:5}]).last()//{a:4,b:5}

Immutable.fromJS({a:1,b:2,c:{d:3,e:4}}).first() //1
Immutable.fromJS({a:1,b:2,c:{d:3,e:4}}).first() //{d:3,e:4}

is()

作用:对两个对象进行比较

用法:is(map1,map2)

简介

和js中对象的比较不同,在js中比较两个对象比较的是地址,

但是在Immutable中比较的是这个对象hashCode和valueOf,只要两个对象的hashCode相等,值就是相同的,避免了深度遍历,提高了性能

代码实现

import { Map, is } from 'immutable'
const map1 = Map({ a: 1, b: 1, c: 1 })
const map2 = Map({ a: 1, b: 1, c: 1 })
map1 === map2   //false
Object.is(map1, map2) // false
is(map1, map2) // true

// is(): 判断两个immutable对象是否相等
const objA = { name: 'graceji', age: 18 };
const objB = { name: 'graceji', age: 18 };
const imA = immutable.Map({ name: 'graceji', age: 18 });
const imB =immutable.Map({ name: 'graceji', age: 18 });
objsA === objB // false; 比较的是地址
immutable.is(imA, imB); // true; hashcode相同

merge , concat

merge

作用:浅合并,新数据与旧数据对比,旧数据中不存在的属性直接添加,就数据中已存在的属性用新数据中的覆盖

mergrWith

作用:自定义浅合并,可自行设置某些属性的值

mergeIn

作用:对深层数据进行浅合并

mergeDeep

作用:深合并,新旧数据中同时存在的的属性为新旧数据合并之后的数据

mergeDeepIn

作用:对深层数据进行深合并

mergrDeepWith

作用:自定义深合并,可自行设置某些属性的值 ’

代码实现

const { Map, List } = require('immutable');
const map1 = Map({ a: 1, b: 2, c: 3, d: 4 });
const map2 = Map({ c: 10, a: 20, t: 30 });
const obj = { d: 100, o: 200, g: 300 };

const map3 = map1.merge(map2, obj);
// Map { a: 20, b: 2, c: 10, d: 100, t: 30, o: 200, g: 300 } 

这里用一段示例彻底搞懂merge,此示例为Map结构,List与Map原理相同

const Map1 = Immutable.fromJS({a:111,b:222,c:{d:333,e:444}}); 
const Map2 = Immutable.fromJS({a:111,b:222,c:{e:444,f:555}}); 
const Map3 = Map1.merge(Map2); 
//Map {a:111,b:222,c:{e:444,f:555}}

const Map4 = Map1.mergeDeep(Map2);  
//Map {a:111,b:222,c:{d:333,e:444,f:555}}

const Map5 = Map1.mergeWith((oldData,newData,key)=>{ 
  if(key === 'a'){ 
    return 666; 
  }else{ 
    return newData 
  } 
},Map2); 
//Map {a:666,b:222,c:{e:444,f:555}}

concat()

作用:对象的拼接,用法与js数组中的concat()相同,返回一个新的对象。

用法:const List = list1.concat(list2)

代码实现

const list1 = List([ 1, 2, 3 ]);
const list2 = List([ 4, 5, 6 ]);
const array = [ 7, 8, 9 ];
const list3 = list1.concat(list2, array);
// List [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

updateIn() 回调函数更新 – 用法参考setIn()


//updateIn 回调函数更新
const nested3 = nested2.updateIn([ 'a', 'b', 'd' ], value => value + 1); 
console.log(nested3); 
// Map { a: Map { b: Map { c: List [ 3, 4, 5 ], d: 7 } } }

const nested4 = nested3.updateIn([ 'a', 'b', 'c' ], list => list.push(6));
// Map { a: Map { b: Map { c: List [ 3, 4, 5, 6 ], d: 7 } } }

toJS()

toJS(): immutable数据转原生js类型的数据 (深度转换,会将内部嵌套的Map和List全部转换成原生js)

用法:value.toJS()

代码实现

const { Map, List } = require('immutable'); 
const deep = Map({ a: 1, b: 2, c: List([ 3, 4, 5 ]) }); 

console.log(deep.toObject()); // { a: 1, b: 2, c: List [ 3, 4, 5 ] }  
console.log(deep.toArray()); // [ 1, 2, List [ 3, 4, 5 ] ]  
console.log(deep.toJS()); // { a: 1, b: 2, c: [ 3, 4, 5 ] }  
JSON.stringify(deep); // '{"a":1,"b":2,"c":[3,4,5]}'

toJS() mmutable===>普通对象

oldImmuObj.toJS()
newImmuObj.toJS()

案例

import React, { Component } from 'react'
import { Map } from 'immutable' 

export default class App extends Component {

  state = {
    info: {
      name: 'demo',
      age: 100
    }
  }
  render() {
    return (
      <div>  
      this.state.info.name --   {this.state.info.name} <br/>
      this.state.info.age --   {this.state.info.age} <br/>
      
      <button onClick={()=>{
        var old = Map(this.state.info)
        var newData = old.set('name','32333').set('age', 1000)
        this.setState({
          info: newData.toJS()
        })
      }}>修改</button>
      </div>
    )
  }
}

fromJS()

fromJS(): 原生js转immutable对象 (深度转换,会将内部嵌套的对象和数组全部转成immutable)

用法:fromJS(value, converter)

简介:value是要转变的数据,converter是要做的操作。第二个参数可不填,默认情况会将数组准换为List类型,将对象转换为Map类型,其余不做操作

const { fromJS } = require('immutable'); 
const nested = fromJS({ a: { b: { c: [ 3, 4, 5 ] } } }); 
// Map { a: Map { b: Map { c: List [ 3, 4, 5 ] } } } 

const obj = fromJS({a:'123',b:'234'},function (key, value, path) {
  console.log(key, value, path)
  return isIndexed(value) ? value.toList() : value.toOrderedMap())
})

总结:增删改查(所有操作都会返回新的值,不会修改原来值)

代码实现

// 增删改查(所有操作都会返回新的值,不会修改原来值)
const immutableData = immutable.fromJS({
    a: 1,
    b: 2c: {
        d: 3
    }
});
const data1 = immutableData.get('a') //  data1 = 1  
const data2 = immutableData.getIn(['c', 'd']) // data2 = 3; getIn用于深层结构访问
const data3 = immutableData.set('a' , 2);   // data3中的 a = 2
const data4 = immutableData.setIn(['c',  'd'],  4);   // data4中的 d = 4
const data5 = immutableData.update('a' , function(x) { return x+4 })   // data5中的 a = 5
const data6 = immutableData.updateIn(['c', 'd'], function(x) { return x+4 })   // data6中的 d = 7
const data7 = immutableData.delete('a')   // data7中的 a 不存在
const data8 = immutableData.deleteIn(['c',  'd'])   // data8中的 d 不存在

案例

import React, { Component } from 'react'
import { fromJS } from 'immutable' 
export default class App extends Component { 
  
  // state = {
  //   info:Map({
  //       name:"demo",
  //       location:Map({
  //           province:"辽宁",
  //           city:"大连"
  //       }),
  //       favor:List(["读书","看报","写代码"])
  //   })
  // }

  // 使用 fromJS 转换成 immutable对象
  state = {
    info:fromJS({  // 注意这里 fromJS -- 转换成 immutable对象
        name:"demo", 
        location:{
            province:"辽宁",
            city:"大连"
        },
        favor:["读书","看报","写代码"]
    })
} 

  render() {
    return (
      <div>
        <h1>个人信息修改</h1> 
        <div>
          {this.state.info.get('name')} <button onClick={()=>{
            this.setState({
              info: this.state.info.set('name','demo33')
              .setIn(['location','city'],'wuhan')  // 注意这里 setIn(['location','city'],'wuhan')
            })
          }}>修改</button>
        </div>
        <div>
          {this.state.info.get('location').get('province')} -- {this.state.info.get('location').get('city')}
        </div>
        <ul>
          {
            this.state.info.get('favor').map((item,index)=><li key={index}>{item} <button onClick={()=>{
              this.setState({
                info: this.state.info
                .updateIn(["favor"],(list)=>list.splice(index,1)) // 注意这里 updateIn(["favor"],(list)=>list.splice(index,1))
              })
            }}>删除</button></li>)
          }
        </ul>
      </div>
    )
  }
}

Immutable-js 优缺点

优点:

降低mutable带来的复杂度

节省内存

历史追溯性(时间旅行)

时间旅行指的是,每时每刻的值都被保留了,想回退到哪一步只要简单的将数据取出就行。

如果现在页面有个撤销的操作,撤销前的数据被保留了,只需要取出就行,这个特性在redux或者flux中特别有用

  • 拥抱函数式编程:immutable本来就是函数式编程的概念,纯函数式编程的特点就是,只要输入一致,输出必然一致,相比于面向对象,这样开发组件和调试更方便

缺点:

需要重新学习api

资源包大小增加(源码5000行左右)

容易与原生对象混淆:由于api与原生不同,混用的话容易出错。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1023917.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux】页表讲解(一级、二级) 和 vm_area_struct ## 对于我前面博客内容的补充

对于前5篇进程相关知识的补充 前言正式开始页表讲解缺页中断页表是如何映射的页表的真正面目 vm_area_structmm_structvm_area_stuct 前言 前面我的博客中讲了很多关于进程的知识&#xff0c;但是有一些内容需要做一点补充&#xff0c;补充完后我的下一篇博客就开始讲线程相关…

云原生Kubernetes:pod亲和性与反亲和性

目录 一、理论 1.调度策略 2.亲和性与反亲和性案例 二、实验 1.亲和性与反亲和性 三、问题 1.节点批次打标签错误 2.for循环批量创建pod报错 四、总结 一、理论 1.调度策略 &#xff08;1&#xff09;对比 2.Pod 拓扑分布约束 &#xff08;1&#xff09;概念 使用 …

游戏ip多开安全指南:保障多重账号操作安全性

游戏多开是许多游戏玩家们常用的操作方式&#xff0c;而使用游戏ip进行游戏多开则能够进一步拓展多重账号的应用。然而&#xff0c;对于游戏多开使用游戏ip的安全性&#xff0c;我们也需要保持一定的警惕和注意事项。本文将为您分享有关游戏ip多开的安全指南&#xff0c;助您保…

C++中operator关键字(重载操作符)

转载地址&#xff1a; https://www.cnblogs.com/ZY-Dream/p/10068993.html operator是C的关键字&#xff0c;它和运算符一起使用&#xff0c;表示一个运算符函数&#xff0c;理解时应将operator整体上视为一个函数名。 这是C 扩展运算符功能的方法&#xff0c;虽然样子古怪&a…

vs2022 创建一个同时支持.net480和.net6.0的WPF项目

新建WPF项目&#xff0c;不要选.NET Framework框架的。如下图所示&#xff0c;选择第一个。&#xff08;选择.NET Framework框架改成.net6.0会报错&#xff09; 用记事本打开项目的csproj文件&#xff0c;修改TargetFrameworks标签&#xff0c;如下所示&#xff1a; <Pro…

C++之容器std::stack类empty、size、top、push、emplace、pop、swap应用总结(二百二十三)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

Bootstrap 框架学习笔记(基础)

来自于 Twitter&#xff0c;基于 HTML、CSS、JavaScript。 有关网站&#xff1a;Bootstrap中文网Bootstrap是Twitter推出的一个用于前端开发的开源工具包。它由Twitter的设计师Mark Otto和Jacob Thornton合作开发&#xff0c;是一个CSS/HTML框架。目前&#xff0c;Bootstrap最…

JVM面试题-类加载顺序、双亲委派、类初始化顺序(详解)

类加载器 JVM只会运行二进制文件&#xff0c;类加载器的作用就是将字节码文件加载到JVM中&#xff0c;从而让Java程序能够启动起来。 类加载负责执行类加载&#xff0c;去磁盘进行识别&#xff0c;识别完后加载到内存 类加载器的种类&#xff1a; 从上往下 启动类加载器&…

Unity的配置文件在安卓路径下使用的方法

Unity的配置文件在安卓路径下使用的方法 前言 之前我做过的很多使用配置文件的Unity项目&#xff0c;后面的有些项目也有在安卓路径下读取json文件的需求。这几天有个需求是获取在安卓路径下配置文件里的数据&#xff0c;我在网上查了一些案例&#xff0c;简单实现了这个需求…

swift 约束布局

添加约束布局 背景图瀑全屏 如何三等分 外面view容器没有约束

Laravel Swagger 使用完整教程

Swagger 使用 一、Swagger 基础1、 什么是Swagger2、 安装过程1 、composer安装2、添加服务提供者&#xff0c;引导框架运行时加载&#xff0c;在 app 配置文件&#xff0c;providers 选项中添加(laravel 5以上忽略此步骤)3、配置完成后&#xff0c;通过输入命令 **php artisan…

QT记事本+登陆界面的简单实现

主体头文件 #ifndef JSB_H #define JSB_H#include <QMainWindow> #include <QMenuBar>//菜单栏 #include <QToolBar>//工具栏 #include <QStatusBar>//状态栏 #include <QTextEdit>//文本 #include <QLabel>//标签 #include <QDebug&g…

什么样的应用程序适合使用Flutter开发桌面?

桌面应用开发的现状 在过去&#xff0c;桌面应用程序的开发通常需要使用特定于操作系统的工具和语言&#xff0c;如C、C#、Java等。这导致了高昂的开发成本和维护困难。尽管有一些跨平台桌面开发工具&#xff0c;如Electron和Qt&#xff0c;但它们在性能、用户体验和开发效率方…

Linus Torvalds接受来自微软的Linux Hyper-V升级

微软最近推送了一些变更&#xff0c;旨在改进即将发布的 Linux 内核 6.6 版本对 Hyper-V 的支持。这些改进包括在 Hyper-V 上支持 AMD SEV-SNP guest 和 Intel TDX guest。除了这两项&#xff0c;还有其他一些升级&#xff0c;如改进了 VMBus 驱动程序中的 ACPI&#xff08;高级…

阿里云产品试用系列-负载均衡 SLB

阿里云负载均衡&#xff08;Server Load Balancer&#xff0c;简称SLB&#xff09;是云原生时代应用高可用的基本要素。通过将流量分发到不同的后端服务来扩展应用系统的服务吞吐能力&#xff0c;消除单点故障并提升应用系统的可用性。阿里云SLB包含面向4层的网络型负载均衡NLB…

Flink TaskManger 内存计算实战

Flink TaskManager内存计算图 计算实例 案例一、假设Task Process内存4GB。 taskmanager.memory.process.size4096m 先排减JVM内存。 JVM Metaspace 固定内存 256mJVM Overhead 固定比例 process * 0.1 4096 * 0.1 410m 得到 Total Flink Memory 4096-256-410 3430m 计…

Palantir的“英伟达时刻”即将到来

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 总结 &#xff08;1&#xff09;由于投资者对生成式人工智能的兴趣持续增加&#xff0c;Palantir的股价一直在上涨。 &#xff08;2&#xff09;Palantir已经连续三个季度实现了GAAP盈利&#xff0c;并将很快有资格被纳入标…

接口幂等性最佳实践--redis+注解

文章目录 一、概念二、常见解决方案三、本文实现四、实现思路五、项目简介六、代码实现1.pom2.JedisUtil3.自定义注解ApiIdempotent4.ApiIdempotentInterceptor拦截器5.TokenServiceImpl6.TestApplication 七、测试验证1.获取token的控制器TokenController2.TestController, 注…

Postman应用——Headers请求头设置

文章目录 Header设置Header删除或禁用Header批量编辑Header预设添加 一般在接口需要校验签名时&#xff0c;Headers请求头用来携带签名和生成签名需要的参数&#xff0c;在Postman也可以设置请求头在接口请求时携带参数。 Header设置 说明&#xff1a; Key&#xff1a;Header…

睿趣科技:新手商家如何做好抖音店铺

抖音&#xff0c;作为全球热门的社交媒体平台之一&#xff0c;不仅仅是分享有趣视频的地方&#xff0c;也是许多商家拓展业务的黄金平台。对于新手商家来说&#xff0c;如何在抖音上建立一个成功的店铺是一项重要的任务。以下是一些关于如何做好抖音店铺的建议。 明确你的目标和…