0%

生命周期的抽象

将LT想象成scope不太容易理解,可以将其想象成链。标注同一个的引用必须共存亡。通过 'a, 多个引用链在一起。
![将引用比作绳子]](https://user-images.githubusercontent.com/24750337/114650520-fb8a8c80-9d14-11eb-93a0-3ee191ff4938.png)

https://doc.rust-lang.org/stable/book/ch10-03-lifetime-syntax.html
https://www.zhihu.com/question/30861652/answer/132841992

为什么生命周期被如此设计

跨函数的变量生存期分析及其复杂,要分析完成各种条件语句,且需要的值只有在运行时才能确认,这就加大了编译器分析的复杂度(又可认为不可能进行分析),Rust通过在函数,结构体上进行生命周期标注,将分析的范围限定到函数内部,从而完成整个分析的过程。这就是为何生命之后需要在 函数, 结构体 上进行 'a 标注

阅读全文 »

我对Pin 的整体理解 - 为了解决unsafe场景下move问题

提出的必要性 - 不依赖Pin能否做到希望的 不被move ?

Pin的作用是防止move,但如果程序员小心处理,那就不会出错。为什么还需要Pin呢?

既然在某些场景下move是错的,那作为安全的编程语言,就需要显式限制这些场景。不能将安全交给人的直觉保证,这是Rust编译器的责任,不是人的

反面例子是C++,程序员犯错的时候还少吗?

阅读全文 »

Rust 基本语法学习

为什么会有此文

目标是给 Deno 项目贡献代码,结果发现我还不会 Rust …,所以要先啃 Rust

我发现 rust,ruby 和掌握的 C 系风格语言很不同。

我从 C# 转 Java 时根本没花时间『特地』学习语法,因为他们两个太像了,直接找了一份开源代码对着抄,边抄边查文档就会了。

阅读全文 »

比如我们有个表(UserLiked)记录用户喜欢的 workspace 内容,且一个用户可以喜欢多个 workspace

前端的 UI 展现是用户点击 like 界面显示出用户全部喜欢的 workspace

现在有下面两种表结构,你觉着哪种不错?

注意,MYSQL并不支持Array类型,这里只是比较表设计。

Mongodb支持Array,文档数据库表结构灵活,不要滥用Array,不要过早优化

阅读全文 »

实现一个功能,根据第一个字段输入的值来动态更改其余字段的类型

比如如下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
interface InputProps {
label: string;
}
interface SelectProps {
name: string;
}
export interface InputType {
input: InputProps;
select: SelectProps;
}
export type FormItemDefinition = {
type: 'input' | 'select';
componentProps?: any
}
阅读全文 »

UseMemo 的使用

FP 组件每次更新渲染都会被调用,我们希望更新时保存上次渲染的状态
比如如下组件 onChange触发之后组件更新,结果输入的值又没了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
const [formData, setFormData] = useState("");
const [formSchema, setFormSchema] = useState(defaultSchema);
return (
<Row>
<Col span={8}>
<div className="pattern-editor">
<Editor
initialCode={JSON.stringify(defaultSchema)}
onChange={() => {}}
></Editor>
</div>
</Col>
<Col span={8}>
<div className="WYSIWYG-editor">
<SchemaForm
schema={formSchema}
onChange={(e) => {
setFormData(JSON.stringify(e.formData));
}}
>
<React.Fragment></React.Fragment>
</SchemaForm>
</div>
</Col>
<Col span={8}>
<div className="config-output">
<Editor
initialCode={JSON.stringify(formData)}
onChange={() => {}}
></Editor>
</div>
</Col>
</Row>
);

而使用useMemo改造后,只要依赖数组不变化,那组件不会被重新渲染,状态还会被保留

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
const [formData, setFormData] = useState("");
const [formSchema, setFormSchema] = useState(defaultSchema);
return (
<Row>
<Col span={8}>
<div className="pattern-editor">
<Editor
initialCode={JSON.stringify(defaultSchema)}
onChange={() => {}}
></Editor>
</div>
</Col>
<Col span={8}>
<div className="WYSIWYG-editor">
{useMemo(
() => (
<SchemaForm
schema={formSchema}
onChange={(e) => {
setFormData(JSON.stringify(e.formData));
}}
>
<React.Fragment></React.Fragment>
</SchemaForm>
),
[formSchema]
)}
</div>
</Col>
<Col span={8}>
<div className="config-output">
{useMemo(
() => (
<Editor
initialCode={JSON.stringify(formData)}
onChange={() => {}}
></Editor>
),
[formData]
)}
</div>
</Col>
</Row>
);
阅读全文 »

我们明明可以在async之后直接调用dispatch,为什么又要多此一举引入中间件呢?

为什么需要中间件来处理Redux异步数据流?

如果异步之后直接Dispatch

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// action creator
function loadData(dispatch, userId) { // needs to dispatch, so it is first argument
return fetch(`http://data.com/${userId}`)
.then(res => res.json())f
.then(
data => dispatch({ type: 'LOAD_DATA_SUCCESS', data }),
err => dispatch({ type: 'LOAD_DATA_FAILURE', err })
);
}

// component
componentWillMount() {
loadData(this.props.dispatch, this.props.userId); // don't forget to pass dispatch
}

如果使用 react-thunk

阅读全文 »

本文转载自 http://jiangew.me/actor-model/

Actor 模型背景

Actor 模型(Actor model)首先是由Carl Hewitt在1973定义, 由Erlang OTP(Open Telecom Platform)推广,其消息传递更加符合面向对象的原始意图。Actors属于并发组件模型,通过组件方式定义并发编程范式的高级阶段,避免使用者直接接触多线程并发或线程池等基础概念。

流行语言并发是基于多线程之间的共享内存,使用同步方法防止写争夺,Actors使用消息模型,每个Actors在同一时间处理最多一个消息,可以发送消息给其他Actors,保证了单独写原则。从而巧妙避免了多线程写争夺。

阅读全文 »

下面是redux的applyMiddleware代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
export default function applyMiddleware(
...middlewares: Middleware[]
): StoreEnhancer<any> {
return (createStore: StoreEnhancerStoreCreator) => <S, A extends AnyAction>(
reducer: Reducer<S, A>,
preloadedState?: PreloadedState<S>
) => {
const store = createStore(reducer, preloadedState)
let dispatch: Dispatch = () => {
throw new Error(
'Dispatching while constructing your middleware is not allowed. ' +
'Other middleware would not be applied to this dispatch.'
)
}

const middlewareAPI: MiddlewareAPI = {
getState: store.getState,
dispatch: (action, ...args) => dispatch(action, ...args)
}
const chain = middlewares.map(middleware => middleware(middlewareAPI))
dispatch = compose<typeof dispatch>(...chain)(store.dispatch)

return {
...store,
dispatch
}
}
}

下面就是Thunk这个中间件的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function createThunkMiddleware(extraArgument) {
return ({ dispatch, getState }) => (next) => (action) => {
if (typeof action === 'function') {
return action(dispatch, getState, extraArgument);
}

return next(action);
};
}

const thunk = createThunkMiddleware();
thunk.withExtraArgument = createThunkMiddleware;

export default thunk;

这个中间件返回了嵌套的函数闭包,其中下面的函数就是applyMiddlewares的 store.dispatch

阅读全文 »