불변성과 반응성을 사용하는 방법
이번에는 Immutable과 React를 어떻게 사용하는지, Immutable과 React를 사용할 때 주의사항은 무엇인지 알아보겠습니다.
Immutable은 React 애플리케이션을 수십 배 향상시킬 수 있습니다. 어떤 사람들은 React가 그 빛을 모를 정도로 인기가 높았기 때문에 최근 JavaScript의 위대한 발명이라고 말합니다. 이 글은 주로 Immutable과 React의 실천을 소개합니다. 필요하신 분들은 참고하시면 됩니다
어떤 사람들은 Immutable이 React 애플리케이션을 수십 배 향상시킬 수 있다고 말합니다. 어떤 사람들은 Immutable의 도입이 JavaScript의 위대한 발명이라고 말합니다. 최근에는 React가 너무 인기가 많았기 때문에 그 빛이 가려졌습니다. 이는 적어도 Immutable이 매우 가치 있다는 것을 보여줍니다. 아래에서 알아보겠습니다.
JavaScript의 객체는 일반적으로 변경 가능(Mutable)합니다. 참조 할당이 사용되기 때문에 새 객체는 단순히 원래 객체를 참조합니다. 새 객체를 변경하면 원래 객체에 영향을 미칩니다. 예를 들어, foo={a: 1}; bar=foo; bar.a=2
이때 foo.a도 2로 변경되었음을 알 수 있습니다. 이렇게 하면 메모리를 절약할 수 있지만 응용 프로그램이 복잡해지면 매우 큰 숨겨진 위험이 발생하고 Mutable이 가져오는 이점보다 이점이 더 커집니다. 이 문제를 해결하기 위한 일반적인 접근 방식은 수정을 피하기 위해shallowCopy(shallow copy)나 deepCopy(deep copy)를 사용하는 것이지만 이 방법은 CPU와 메모리의 낭비를 초래합니다.
Immutable은 이러한 문제를 매우 효과적으로 해결할 수 있습니다. foo={a: 1}; bar=foo; bar.a=2
你会发现此时 foo.a 也被改成了 2。虽然这样做可以节约内存,但当应用复杂后,这就造成了非常大的隐患,Mutable 带来的优点变得得不偿失。为了解决这个问题,一般的做法是使用 shallowCopy(浅拷贝)或 deepCopy(深拷贝)来避免被修改,但这样做造成了 CPU 和内存的浪费。
Immutable 可以很好地解决这些问题。
什么是 Immutable Data
Immutable Data 就是一旦创建,就不能再被更改的数据。对 Immutable 对象的任何修改或添加删除操作都会返回一个新的 Immutable 对象。Immutable 实现的原理是 Persistent Data Structure(持久化数据结构),也就是使用旧数据创建新数据时,要保证旧数据同时可用且不变。同时为了避免 deepCopy 把所有节点都复制一遍带来的性能损耗,Immutable 使用了 Structural Sharing(结构共享),即如果对象树中一个节点发生变化,只修改这个节点和受它影响的父节点,其它节点则进行共享。请看下面动画:
擦,费了好大劲做了个 Gif 动画,竟然被强制转成了静态图,请移步 http://img.alicdn.com/tps/i2/TB1zzi_KXXXXXctXFXXbrb8OVXX-613-575.gif 观看
目前流行的 Immutable 库有两个:
1.immutable.js
Facebook 工程师 Lee Byron 花费 3 年时间打造,与 React 同期出现,但没有被默认放到 React 工具集里(React 提供了简化的 Helper)。它内部实现了一套完整的 Persistent Data Structure,还有很多易用的数据类型。像 Collection、List、Map、Set、Record、Seq。有非常全面的map、filter、groupBy、reduce``find函数式操作方法。同时 API 也尽量与 Object 或 Array 类似。
其中有 3 种最重要的数据结构说明一下:(Java 程序员应该最熟悉了)
Map:键值对集合,对应于 Object,ES6 也有专门的 Map 对象
List:有序可重复的列表,对应于 Array
Set:无序且不可重复的列表
2.seamless-immutable
与 Immutable.js 学院派的风格不同,seamless-immutable
불변 데이터는 한번 생성되면 변경할 수 없는 데이터입니다. Immutable 객체를 수정, 추가 또는 삭제하면 새로운 Immutable 객체가 반환됩니다. Immutable의 구현 원칙은 영구 데이터 구조입니다. 즉, 이전 데이터를 사용하여 새 데이터를 생성할 때 이전 데이터가 사용 가능하고 동시에 변경되지 않도록 보장해야 합니다. 동시에, deepCopy가 모든 노드를 복사하여 발생하는 성능 손실을 방지하기 위해 Immutable은 구조적 공유(구조적 공유)를 사용합니다. 즉, 객체 트리의 노드가 변경되면 해당 노드와 상위 노드만 영향을 받습니다. 수정되고 다른 노드도 수정되어 공유됩니다. 아래 애니메이션을 봐주세요:
Gif 애니메이션을 만들려고 노력을 많이 했는데 강제로 정적 이미지로 변환되었습니다. http://img .alicdn.com/tps/i2/TB1zzi_KXXXXXctXFXXbrb8OVXX-613-575.gif 시청1.immutable.js Lee Byron, Facebook Engineer 지출 빌드하는데 3년이 걸렸고 React와 동시에 등장했지만 기본적으로 React 도구 세트에 포함되지 않았습니다(React는 단순화된 Helper를 제공합니다). 내부적으로 완전한 영구 데이터 구조 세트와 사용하기 쉬운 다양한 데이터 유형
현재 널리 사용되는 두 가지 불변 라이브러리가 있습니다:
을 구현합니다. . Collection, List, Map, Set, Record, Seq와 같습니다. 매우 포괄적인 맵, 필터, 그룹별, 축소 및 기능적 작업 방법 찾기가 있습니다. 동시에 API는 객체 또는 배열과 최대한 유사합니다.
설명해야 할 가장 중요한 3가지 데이터 구조가 있습니다: (Java 프로그래머가 가장 익숙할 것입니다.)
Map: Object에 해당하는 키-값 쌍의 모음, ES6에는 특수 Map 객체도 있습니다
List: 배열
Set에 해당하는 순서 있는 반복 가능 목록: 순서가 없고 반복되지 않는 목록2.seamless-immutable
seamless-immutable 코드 >는 완전한 영구 데이터 구조를 구현하지 않지만 Object.defineProperty(IE9 이상에서만 사용할 수 있음)를 사용하여 JavaScript의 Array 및 Object 개체를 확장합니다. API는 Array 및 Object 기반입니다. on 배열 및 객체와 동일합니다. 코드 기반은 매우 작으며 압축하여 다운로드할 경우 2K에 불과합니다. Immutable.js는 16K로 압축됩니다. 🎜🎜둘 사이의 차이를 느끼기 위한 아래 코드:🎜<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">// 原来的写法
let foo = {a: {b: 1}};
let bar = foo;
bar.a.b = 2;
console.log(foo.a.b); // 打印 2
console.log(foo === bar); // 打印 true
// 使用 immutable.js 后
import Immutable from ‘immutable';
foo = Immutable.fromJS({a: {b: 1}});
bar = foo.setIn([‘a', ‘b'], 2); // 使用 setIn 赋值
console.log(foo.getIn([‘a', ‘b'])); // 使用 getIn 取值,打印 1
console.log(foo === bar); // 打印 false
// 使用 seamless-immutable.js 后
import SImmutable from ‘seamless-immutable';
foo = SImmutable({a: {b: 1}})
bar = foo.merge({a: { b: 2}}) // 使用 merge 赋值
console.log(foo.a.b); // 像原生 Object 一样取值,打印 1
console.log(foo === bar); // 打印 false</pre><div class="contentsignin">로그인 후 복사</div></div>🎜🎜🎜Immutable의 장점🎜🎜🎜🎜🎜1 Immutable은 Mutable🎜🎜🎜Variable(Mutable) 데이터가 시간과 가치를 결합하는 개념으로 만듭니다. 데이터를 다시 추적하기가 어렵습니다. 🎜🎜예를 들어 다음 코드는 🎜<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">function touchAndLog(touchFn) {
let data = { key: ‘value' };
touchFn(data);
console.log(data.key); // 猜猜会打印什么?
}</pre><div class="contentsignin">로그인 후 복사</div></div>🎜 touchFn의 코드를 보지 않고는 데이터에 어떤 영향을 미칠지 모르기 때문에 무엇이 인쇄될지 알 수 없습니다. (이건 말도 안되는 소리 아닌가요? ). 하지만 데이터가 Immutable이면 값이 인쇄되는 것을 확실히 알 수 있습니다. 🎜🎜🎜🎜2. 메모리 절약🎜🎜🎜<p style="text-align: left;">Immutable.js 使用了 Structure Sharing 会尽量复用内存。没有被引用的对象会被垃圾回收。</p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">import { Map} from ‘immutable';
let a = Map({
select: ‘users',
filter: Map({ name: ‘Cam' })
})
let b = a.set(‘select', ‘people');
a === b; // false
a.get(‘filter') === b.get(‘filter'); // true</pre><div class="contentsignin">로그인 후 복사</div></div>
<p style="text-align: left;">上面 a 和 b 共享了没有变化的 `filter` 节点。</p>
<p style="text-align: left;"><span style="color: #ff0000"><strong>3 . Undo/Redo,Copy/Paste,甚至时间旅行这些功能做起来小菜一碟</strong></span></p>
<p style="text-align: left;">因为每次数据都是不一样的,只要把这些数据放到一个数组里储存起来,想回退到哪里就拿出对应数据即可,很容易开发出撤销重做这种功能。</p>
<p style="text-align: left;">后面我会提供 Flux 做 Undo 的示例。</p>
<p style="text-align: left;"><span style="color: #ff0000"><strong>4 . 并发安全</strong></span></p>
<p style="text-align: left;">传统的并发非常难做,因为要处理各种数据不一致问题,因此『聪明人』发明了各种锁来解决。但使用了 Immutable 之后,数据天生是不可变的,并发锁就不需要了。</p>
<p style="text-align: left;">然而现在并没什么卵用,因为 JavaScript 还是单线程运行的啊。但未来可能会加入,提前解决未来的问题不也挺好吗?</p>
<p style="text-align: left;"><span style="color: #ff0000"><strong>拥抱函数式编程</strong></span></p>
<p style="text-align: left;">Immutable 本身就是函数式编程中的概念,纯函数式编程比<a href="http://www.php.cn/code/6286.html" target="_blank">面向对象</a>更适用于前端开发。因为只要输入一致,输出必然一致,这样开发的组件更易于调试和组装。</p>
<p style="text-align: left;">像 ClojureScript,Elm 等函数式编程语言中的数据类型天生都是 Immutable 的,这也是为什么 ClojureScript 基于 React 的框架 — Om 性能比 React 还要好的原因。</p>
<p style="text-align: left;"><span style="color: #ff0000"><strong>使用 Immutable 的缺点</strong></span></p>
<p style="text-align: left;">需要学习新的 API</p>
<p style="text-align: left;">No Comments</p>
<p style="text-align: left;">增加了资源文件大小</p>
<p style="text-align: left;">No Comments</p>
<p style="text-align: left;">容易与原生对象混淆</p>
<p style="text-align: left;">这点是我们使用 Immutable.js 过程中遇到最大的问题。写代码要做思维上的转变。</p>
<p style="text-align: left;">虽然 Immutable.js 尽量尝试把 API 设计的原生对象类似,有的时候还是很难区别到底是 Immutable 对象还是原生对象,容易混淆操作。</p>
<p style="text-align: left;">Immutable 中的 Map 和 List 虽对应原生 Object 和 Array,但操作非常不同,比如你要用 map.get(‘key') 而不是 map.key,array.get(0) 而不是 array[0]。另外 Immutable 每次修改都会返回新对象,也很容易忘记赋值。</p>
<p style="text-align: left;">当使用外部库的时候,一般需要使用原生对象,也很容易忘记转换。</p>
<p style="text-align: left;">下面给出一些办法来避免类似问题发生:</p>
<p style="text-align: left;">使用 Flow 或 TypeScript 这类有静态类型检查的工具</p>
<p style="text-align: left;">约定<a href="http://www.php.cn/code/12015.html" target="_blank">变量命名规则</a>:如所有 Immutable 类型对象以 $$ 开头。</p>
<p style="text-align: left;">使用 Immutable.fromJS 而不是 Immutable.Map 或 Immutable.List 来<a href="http://www.php.cn/wiki/69.html" target="_blank">创建对象</a>,这样可以避免 Immutable 和原生对象间的混用。</p>
<p style="text-align: left;"><strong>更多认识</strong></p>
<p style="text-align: left;"><span style="color: #ff0000"><strong>1 . Immutable.is</strong></span></p>
<p style="text-align: left;">两个 immutable 对象可以使用 === 来比较,这样是直接比较内存地址,性能最好。但即使两个对象的值是一样的,也会返回 false:</p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">let map1 = Immutable.Map({a:1, b:1, c:1});
let map2 = Immutable.Map({a:1, b:1, c:1});
map1 === map2; // false</pre><div class="contentsignin">로그인 후 복사</div></div>
<p style="text-align: left;">为了直接比较对象的值,immutable.js 提供了 Immutable.is 来做『值比较』,结果如下:</p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">Immutable.is(map1, map2); // true</pre><div class="contentsignin">로그인 후 복사</div></div>
<p style="text-align: left;">Immutable.is 比较的是两个对象的 hashCode 或 valueOf(对于 JavaScript 对象)。由于 immutable 内部使用了 Trie 数据结构来存储,只要两个对象的 hashCode 相等,值就是一样的。这样的算法避免了深度遍历比较,性能非常好。</p>
<p style="text-align: left;">后面会使用 Immutable.is 来减少 React 重复渲染,提高性能。</p>
<p style="text-align: left;">另外,还有 mori、cortex 等,因为类似就不再介绍。</p>
<p style="text-align: left;"><span style="color: #ff0000"><strong>2 . 与 Object.freeze、const 区别</strong></span></p>
<p style="text-align: left;">Object.freeze 和 ES6 中新加入的 const 都可以达到防止对象被篡改的功能,但它们是 shallowCopy 的。对象层级一深就要特殊处理了。</p>
<p style="text-align: left;"><span style="color: #ff0000"><strong>3 . Cursor 的概念</strong></span></p>
<p style="text-align: left;">这个 Cursor 和数据库中的游标是完全不同的概念。</p>
<p style="text-align: left;">由于 Immutable 数据一般嵌套非常深,为了便于访问深层数据,Cursor 提供了可以直接访问这个深层数据的引用。</p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">import Immutable from ‘immutable';
import Cursor from ‘immutable/contrib/cursor';
let data = Immutable.fromJS({ a: { b: { c: 1 } } });
// 让 cursor 指向 { c: 1 }
let cursor = Cursor.from(data, [‘a', ‘b'], newData => {
// 当 cursor 或其子 cursor 执行 update 时调用
console.log(newData);
});
cursor.get(‘c'); // 1
cursor = cursor.update(‘c', x => x + 1);
cursor.get(‘c'); // 2</pre><div class="contentsignin">로그인 후 복사</div></div>
<p style="text-align: left;"><span style="color: #ff0000"><strong>实践</strong></span></p>
<p style="text-align: left;">与 React 搭配使用,Pure Render</p>
<p style="text-align: left;">熟悉 React 的都知道,React 做<a href="http://www.php.cn/html/html-jsyouhua.html" target="_blank">性能优化</a>时有一个避免重复渲染的大招,就是使用 shouldComponentUpdate(),但它默认返回 true,即始终会执行 render() 方法,然后做 Virtual DOM 比较,并得出是否需要做真实 DOM 更新,这里往往会带来很多无必要的渲染并成为性能瓶颈。</p>
<p style="text-align: left;">当然我们也可以在<code> shouldComponentUpdate()
中使用使用 deepCopy 和 deepCompare 来避免无必要的 render(),但 deepCopy 和 deepCompare 一般都是非常耗性能的。
Immutable 则提供了简洁高效的判断数据是否变化的方法,只需 === 和 is 比较就能知道是否需要执行 render(),而这个操作几乎 0 成本,所以可以极大提高性能。修改后的 shouldComponentUpdate
是这样的:
import { is } from ‘immutable'; shouldComponentUpdate: (nextProps = {}, nextState = {}) => { const thisProps = this.props || {}, thisState = this.state || {}; if (Object.keys(thisProps).length !== Object.keys(nextProps).length || Object.keys(thisState).length !== Object.keys(nextState).length) { return true; } for (const key in nextProps) { if (thisProps[key] !== nextProps[key] || !is(thisProps[key], nextProps[key])) { return true; } } for (const key in nextState) { if (thisState[key] !== nextState[key] || !is(thisState[key], nextState[key])) { return true; } } return false; }
使用 Immutable 后,如下图,当红色节点的 state 变化后,不会再渲染树中的所有节点,而是只渲染图中绿色的部分:
你也可以借助 React.addons.PureRenderMixin
或支持 class 语法的pure-render-decorator
来实现。
setState 的一个技巧
React 建议把 this.state 当作 Immutable 的,因此修改前需要做一个 deepCopy,显得麻烦:
import ‘_' from ‘lodash'; const Component = React.createClass({ getInitialState() { return { data: { times: 0 } } }, handleAdd() { let data = _.cloneDeep(this.state.data); data.times = data.times + 1; this.setState({ data: data }); // 如果上面不做 cloneDeep,下面打印的结果会是已经加 1 后的值。 console.log(this.state.data.times); } }
使用 Immutable 后:
getInitialState() { return { data: Map({ times: 0 }) } }, handleAdd() { this.setState({ data: this.state.data.update(‘times', v => v + 1) }); // 这时的 times 并不会改变 console.log(this.state.data.get(‘times')); }
上面的 `handleAdd` 可以简写成:
handleAdd() { this.setState(({data}) => ({ data: data.update(‘times', v => v + 1) }) }); }
2 . 与 Flux 搭配使用
由于 Flux 并没有限定 Store 中数据的类型,使用 Immutable 非常简单。
现在是实现一个类似带有添加和撤销功能的 Store:
import { Map, OrderedMap } from ‘immutable'; let todos = OrderedMap(); let history = []; // 普通数组,存放每次操作后产生的数据 let TodoStore = createStore({ getAll() { return todos; } }); Dispatcher.register(action => { if (action.actionType === ‘create') { let id = createGUID(); history.push(todos); // 记录当前操作前的数据,便于撤销 todos = todos.set(id, Map({ id: id, complete: false, text: action.text.trim() })); TodoStore.emitChange(); } else if (action.actionType === ‘undo') { // 这里是撤销功能实现, // 只需从 history 数组中取前一次 todos 即可 if (history.length > 0) { todos = history.pop(); } TodoStore.emitChange(); } });
3 . 与 Redux 搭配使用
Redux 是目前流行的 Flux 衍生库。它简化了 Flux 中多个 Store 的概念,只有一个 Store,数据操作通过 Reducer 中实现;同时它提供更简洁和清晰的单向数据流(View -> Action -> Middleware -> Reducer),也更易于开发同构应用。目前已经在我们项目中大规模使用。
由于 Redux 中内置的 combineReducers 和 reducer 中的 initialState 都为原生的 Object 对象,所以不能和 Immutable 原生搭配使用。
幸运的是,Redux 并不排斥使用 Immutable,可以自己重写 combineReducers 或使用 redux-immutablejs 来提供支持。
上面我们提到 Cursor 可以方便检索和 update 层级比较深的数据,但因为 Redux 中已经有了 select 来做检索,Action 来更新数据,因此 Cursor 在这里就没有用武之地了。
总结
Immutable 可以给应用带来极大的性能提升,但是否使用还要看项目情况。由于侵入性较强,新项目引入比较容易,老项目迁移需要评估迁移。对于一些提供给外部使用的公共组件,最好不要把 Immutable 对象直接暴露在对外接口中。
如果 JS 原生 Immutable 类型会不会太美,被称为 React API 终结者的 Sebastian Markbåge 有一个这样的提案,能否通过现在还不确定。不过可以肯定的是 Immutable 会被越来越多的项目使用。
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
위 내용은 불변성과 반응성을 사용하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

MetaMask(중국어로 Little Fox Wallet이라고도 함)는 무료이며 호평을 받는 암호화 지갑 소프트웨어입니다. 현재 BTCC는 MetaMask 지갑에 대한 바인딩을 지원합니다. 바인딩 후 MetaMask 지갑을 사용하여 빠르게 로그인하고 가치를 저장하고 코인을 구매할 수 있으며 첫 바인딩에는 20 USDT 평가판 보너스도 받을 수 있습니다. BTCCMetaMask 지갑 튜토리얼에서는 MetaMask 등록 및 사용 방법, BTCC에서 Little Fox 지갑을 바인딩하고 사용하는 방법을 자세히 소개합니다. MetaMask 지갑이란 무엇입니까? 3천만 명 이상의 사용자를 보유한 MetaMask Little Fox Wallet은 오늘날 가장 인기 있는 암호화폐 지갑 중 하나입니다. 무료로 사용할 수 있으며 확장으로 네트워크에 설치할 수 있습니다.

오늘날 클라우드 스토리지는 우리의 일상 생활과 업무에 없어서는 안 될 부분이 되었습니다. 중국 최고의 클라우드 스토리지 서비스 중 하나인 Baidu Netdisk는 강력한 스토리지 기능, 효율적인 전송 속도 및 편리한 운영 경험으로 많은 사용자의 호감을 얻었습니다. 중요한 파일을 백업하고, 정보를 공유하고, 온라인으로 비디오를 시청하고, 음악을 듣고 싶은 경우 Baidu Cloud Disk는 귀하의 요구를 충족할 수 있습니다. 그러나 많은 사용자가 Baidu Netdisk 앱의 구체적인 사용 방법을 이해하지 못할 수 있으므로 이 튜토리얼에서는 Baidu Netdisk 앱 사용 방법을 자세히 소개합니다. Baidu 클라우드 네트워크 디스크 사용 방법: 1. 설치 먼저 Baidu Cloud 소프트웨어를 다운로드하고 설치할 때 사용자 정의 설치 옵션을 선택하십시오.

NetEase Mailbox는 중국 네티즌들이 널리 사용하는 이메일 주소로, 안정적이고 효율적인 서비스로 항상 사용자들의 신뢰를 얻어 왔습니다. NetEase Mailbox Master는 휴대폰 사용자를 위해 특별히 제작된 이메일 소프트웨어로 이메일 보내기 및 받기 프로세스를 크게 단순화하고 이메일 처리를 더욱 편리하게 만듭니다. 따라서 NetEase Mailbox Master를 사용하는 방법과 그 기능이 무엇인지 아래에서 이 사이트의 편집자가 자세한 소개를 제공하여 도움을 드릴 것입니다! 먼저, 모바일 앱스토어에서 NetEase Mailbox Master 앱을 검색하여 다운로드하실 수 있습니다. App Store 또는 Baidu Mobile Assistant에서 "NetEase Mailbox Master"를 검색한 후 안내에 따라 설치하세요. 다운로드 및 설치가 완료되면 NetEase 이메일 계정을 열고 로그인합니다. 로그인 인터페이스는 아래와 같습니다.

Xiaomi 자동차 소프트웨어는 원격 자동차 제어 기능을 제공하여 사용자가 휴대폰이나 컴퓨터를 통해 차량의 문과 창문을 열고 닫고, 엔진 시동을 걸고, 차량의 에어컨과 오디오를 제어하는 등 차량을 원격으로 제어할 수 있습니다. 다음은 이 소프트웨어의 사용법과 내용에 대해 함께 알아봅시다. Xiaomi Auto 앱 기능 및 사용 방법의 전체 목록 1. Xiaomi Auto 앱은 3월 25일 Apple AppStore에 출시되었으며 이제 Android 휴대폰의 앱 스토어에서 다운로드할 수 있습니다. 자동차 구매: Xiaomi Auto의 핵심 특징과 기술 매개 변수를 이해합니다. , 시승 예약을 하고 Xiaomi 차량을 구성 및 주문하고 차량 픽업 작업 항목의 온라인 처리를 지원하세요. 3. 커뮤니티: Xiaomi Auto 브랜드 정보를 이해하고, 자동차 경험을 교환하고, 멋진 자동차 생활을 공유하세요. 4. 자동차 제어: 휴대폰은 원격 제어, 원격 제어, 실시간 보안, 간편함을 제공합니다.

Go 언어는 간단하고 효율적이며 동시성이 뛰어난 프로그래밍 언어입니다. Google에서 개발한 오픈 소스 언어입니다. Go 언어에서는 공백 사용이 매우 중요하며, 이는 코드의 가독성과 유지 관리성을 향상시킬 수 있습니다. 이 글에서는 Go 언어에서 공백을 올바르게 사용하는 방법을 소개하고 구체적인 코드 예제를 제공합니다. 공백을 올바르게 사용해야 하는 이유 프로그래밍 과정에서 공백의 사용은 코드의 가독성과 아름다움을 위해 매우 중요합니다. 공백을 적절하게 사용하면 코드가 더 명확하고 읽기 쉬워집니다.

Java 프레임워크와 React 프레임워크의 통합: 단계: 백엔드 Java 프레임워크를 설정합니다. 프로젝트 구조를 만듭니다. 빌드 도구를 구성합니다. React 애플리케이션을 만듭니다. REST API 엔드포인트를 작성합니다. 통신 메커니즘을 구성합니다. 실제 사례(SpringBoot+React): Java 코드: RESTfulAPI 컨트롤러를 정의합니다. React 코드: API에서 반환된 데이터를 가져오고 표시합니다.

전각 문자란 무엇입니까? 컴퓨터 인코딩 시스템에서 이중 너비 문자는 두 개의 표준 문자 위치를 차지하는 문자 인코딩 방법입니다. 이에 표준 문자 위치를 차지하는 문자 인코딩 방식을 반각문자라 한다. 전자 문자는 일반적으로 중국어, 일본어, 한국어 및 기타 아시아 문자의 입력, 표시 및 인쇄에 사용됩니다. 중국어 입력 방법과 텍스트 편집에서는 전자와 반각 문자의 사용 시나리오가 다릅니다. 전각문자 사용 중국어 입력방법 : 중국어 입력방법에서는 한자, 기호 등의 한자를 입력할 때 일반적으로 전각문자를 사용한다.

BitgetLaunchpool은 모든 암호화폐 애호가를 위해 설계된 동적 플랫폼입니다. BitgetLaunchpool은 독특한 제품으로 돋보입니다. 여기에서 토큰을 스테이킹하여 에어드랍, 높은 보상, 초기 참가자에게만 제공되는 넉넉한 상금 풀 등 더 많은 보상을 잠금 해제할 수 있습니다. BitgetLaunchpool이란 무엇인가요? BitgetLaunchpool은 사용자 친화적인 이용 약관에 따라 토큰을 스테이킹하고 획득할 수 있는 암호화폐 플랫폼입니다. Launchpool에 BGB 또는 기타 토큰을 투자함으로써 사용자는 무료 에어드랍, 수익을 받고 넉넉한 보너스 풀에 참여할 수 있는 기회를 갖게 됩니다. 담보자산의 수입은 T+1시간 이내에 계산되며, 보상은 다음을 기준으로 합니다.
