V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  CLMan  ›  全部回复第 4 页 / 共 8 页
回复总数  148
1  2  3  4  5  6  7  8  
1. JS 的 async 会将返回结果自动包装为 Future ,Dart 也是类似的原理。异步函数会异步执行,返回结果为 Future 类型,跟里面是否使用 await 没什么关系。

你所认为的同步,其实只是因为你这测试用例过于简单,只有 A,B ,给你带来的错觉。

2. 你为什么会认为“遇到 B 函数的 Future.delay 时直接返回了 Future 对象给 A”,你用打印下结果就知道不是你想得那样:
//修改 A 函数的 print(B());为:
var result = B();
result.then((value) => print(value));

3. await 有两个作用:1. 让“await doSomething()”的 doSomething()异步执行( JS,DART 就是“抛事件循环”,其它语言可能就是多线程、协程等) 2. 等待 doSomething()对应的异步任务执行完成,然后再执行剩余部分。所以只有 B 执行完后,才返回执行 A 的后半部分,也就是你说的“同步调用 B 函数第一行打印语句”。

“抛事件循环”,是一种抽象化的模型,容易让人理解得云里雾里。沿用这种模型来说明,应该是先抛 B()到事件循环,再抛 A 的剩余部分到事件循环。

事实上,当 JS 和 Dart 的代码混合了异步逻辑,很难只用事件模型来描述代码的执行情况。比如,假设 B()函数里面`await C()`,那 C()是不是就抛到 A 的剩余部分后面了,岂不是 A 的剩余部分还先于 C()执行。当然,你可以再给这个模型补充很多细节,问题是这些细节就牵涉到具体的实现,比如 chrome,mozilla,quickjs 等完全可以采用不同的底层实现。

这并不是说事件模型是错误的,只是说当存在异步逻辑时,事件模型需要补充很多细节,不然就会像你一样陷入混乱,此时可以不用事件模型来理解程序的执行。

4. 不了解,我这里 IDE 提示:“可以去掉 await ,且 await 无效”。无论是还是不是,这种代码没有啥实际价值。
336 天前
回复了 tlerbao 创建的主题 程序员 前端:大家的 API 都是怎么导入导出的?
@CLMan 补充下,默认导出目前还是有一些应用场景:

- 使用 JS/TS 作为配置文件,rollup,jest,vite 等框架的配置文件都是采用默认导出

除了以上场景,一般情况下自己的代码都没有必须使用默认导出的必要。
洋洋洒洒写了那么多,其实最关键的继承家业却没提,属实典中典了。
337 天前
回复了 tlerbao 创建的主题 程序员 前端:大家的 API 都是怎么导入导出的?
@CLMan 我翻了下 ECMAScript 的早期相关讨论,终于找到了一个相关文档: https://archives.ecma-international.org/2014/misc/2014misc6.html

这个文档证明了我的以上猜测,默认导出设计的初衷就是为了兼容类似 jQuery 这样 ES6 之前的流行的 JS 使用模式(全局单例对象),也确实如文档所说,给当时的 JS 使用者以及后来的 JS/TS 使用者造成了混乱。

这是典型的编程语言设计时因缺乏长远考虑,给后来的使用者带来困扰,后来的使用者还必须得考古才能理解其应用场景,了解语言的缺陷仅为了避免使用该缺陷是当代的编程语言学习者常常面临的情况。
337 天前
回复了 tlerbao 创建的主题 程序员 前端:大家的 API 都是怎么导入导出的?
这个可以参考 google typescript style guidle ,只需要使用 1 ,不建议使用 2,3 ,也没有什么必须使用 2,3 的场景。

至于上面说的桶文件,其实更多是基于兼容性和习惯( Deno 作者吐槽为设计错误),并不是说这种设计就是好的。通常情况下,仅限于包级别使用( src/index.js )。

如果考虑浏览器兼容,需要 iife 模式(脚本模式),rollup 对 1,2 产生相同的结果,因此也不需要必须使用默认导出。

我也不知道当初 es 是为啥设计默认导出,我一直以来猜测是为了兼容 iife 模式,一个库提供一个全局对象,避免污染 global 作用域。但没有证据能证明我的猜测。
可以从学历,年龄,知识,经验四个维度来评估自己。从个体上来讲,一切皆有可能。从群体大数据上来讲,在这行业以 **技术** 立足的可能性微乎其微。

你目前的情况可能也就本科计算机大二水平,而人家有学历(学习能力)、年龄的优势。

如果只是单纯当个兴趣,可能也就 python,javascript 适合没有太多计算机科学背景的人学习,用来完成一些自己的项目。
348 天前
回复了 huiwang520 创建的主题 程序员 我对 Go 和 Rust 的看法
如果你 10 年前说出这样的话,说明你有远见。

但今天再说这样的话,就属于正确的废话,放自己笔记或者丢评论区没啥,发帖就属于浪费大家时间。
因为`func (h *IntHeap) Pop()`是 golang 的 heap 的实现细节:

type Interface interface {
sort.Interface
Push(x any) // add x as element Len()
Pop() any // remove and return element Len() - 1.
}

而真正堆的 pop 方法是`heap.Pop()`函数,别把两者弄混了。
两个内存大户,谈体验的话,都谈不上好。
351 天前
回复了 xlinux 创建的主题 git git 文件 EOL 的疑惑
@CLMan 补充一下,我实际测试过:

- eol 设定不存在强制效果,只会在提交时当本地文件的 eol 与设定和存档文件均不一致时才提示转换
- 如果本地文件的 eof 与存档文件的 eof 一致,即使违背了 eol 设定,那么 git 不会提示也不会转换
351 天前
回复了 xlinux 创建的主题 git git 文件 EOL 的疑惑
·EOL·是 end of line 的缩写,表示仓库中文本文件应当使用的换行符,可以通过`core.eol`( etc/gitconfig,~/.gitconfig )来设定,或者.gitattributes 的`* text=auto eol=lf`类似指令来设定,默认为 native 。

`core.autocrlf`( etc/gitconfig,~/.gitconfig )可以指定当文件的 eof 与设定不同时,是否在检出和提交代码时进行转换。

回答里的问题:

1. “在 windows 查看文件 a 、b 的 eol 格式都是 crlf”,因为你没在~/.gitconfig 中设定,所以使用 etc/gitconfig 里面的默认设定,如果你是手动安装的 git ,在你安装时的选项会最终保存在该文件,不同 client ,比如 github desktop 或者 fork 等,可能会使用它们自带的 git
2. “在 linux 查看文件 a 、b 的 eol 格式都是 lf”与 1 同理
3. “ZIP ,查看文件 a 为 crlf ,b 为 lf ”,ZIP 里面存储的是原始文件,并不会受到 autocrlf,eof 的设置影响

特别是 3 ,这些设置本质上是影响 git 这个软件的逻辑,并不会直接影响实际存储的数据
@drymonfidelia 在我本机上实测,可以正确设置 header 。
@drymonfidelia 我前面给出的方案修复了你代码里面的语法错误,你都不看一眼吗?
@CLMan 需要添加依赖(为了避免兼容性问题,与你使用的 tauri 版本保持一致,可以使用 IDE 的依赖管理功能查看)

[dependencies]
webview2-com = "0.19.1"
windows = "0.39.0"
你的思路没什么问题,但知识储备跟不上,这个问题涉及到 win32 api ,而且 rust 语言本身是一个很难学的语言。

下面是解决方案:
-----
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

use tauri::Manager;
use webview2_com::{Microsoft::Web::WebView2::Win32::{ICoreWebView2WebResourceRequest, COREWEBVIEW2_WEB_RESOURCE_CONTEXT_ALL}, WebResourceRequestedEventHandler};
use windows::{core::HSTRING, Win32::System::WinRT::EventRegistrationToken};

fn main() {
tauri::Builder::default()
.setup(|app| {
let main_window = app.get_window("main").unwrap();
main_window.with_webview(|webview| unsafe {
let core = webview.controller().CoreWebView2().unwrap();
let mut _token: EventRegistrationToken = EventRegistrationToken::default();
core.AddWebResourceRequestedFilter(&HSTRING::from("*"), COREWEBVIEW2_WEB_RESOURCE_CONTEXT_ALL).unwrap();
core.add_WebResourceRequested(
&WebResourceRequestedEventHandler::create(Box::new(move |_webview, args| {
if let Some(args) = args {
let request: ICoreWebView2WebResourceRequest = args.Request().unwrap();
request
.Headers()
.unwrap()
.SetHeader(&HSTRING::from("key1"), &HSTRING::from("value1"))
.unwrap();
}
Ok(())
})), &mut _token).unwrap();
}).unwrap();
Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
用一个你没学过的(复杂)语言,干一件你不熟悉的事情(使用 tauri 框架),然后怪这东西太难用了。
357 天前
回复了 wednesdayco 创建的主题 TypeScript 这种的类型是不是实现不了(TypeScript)
好奇什么场景需要这么复杂的类型定义呢?

或者说类似问题的类型约束的严谨性和代码简洁应该如何取舍?

我个人是把 TS 当作一个不太完美的类型约束工具,更倾向于代码简洁性。
https://imgur.com/a/YiUkw4T

上面丢失了层次,给个图像(这是之前没用 go mod ,后来添加了 go.mod )。

用啥都能刷吧,主要是层次清晰就 OK ,Go 和 Rust 都挺适合用 vscode 写,语言官方自带测试工具,写单元测试也容易。

个人更喜欢用 Go ,不需要任何语法负担。

至于复习,我个人刷题主要是练习题感,并没有期望面试遇到原题,复习更多是从系统的数据结构与算法知识层面。
我服了,随便按个键就自动回复了,啥设定啊。
------
每个题独立的包或者模块,我刷题主要用 Go ,也用过 Rust ,共存在一个项目里面。

结构如下( question1,question2 替换为对应问题的 url 路径,连字符 rust 用_,go 用-):
```
go.mod
Cargo.toml
src/
array/
question1/
solution_test.go
question2.rs
mod.rs
dp/
hash/
...
lib.rs
```
示例代码( contains-duplicate-iii.rs ):
```
struct Solution {}

// https://leetcode-cn.com/problems/contains-duplicate-iii/
// 参考题解: https://leetcode-cn.com/problems/contains-duplicate-iii/solution/cun-zai-zhong-fu-yuan-su-iii-by-leetcode-bbkt/
// 考点:滑动窗口、桶排序
//
// 一种朴素算法是计算所有可能的差值,时间复杂度为 kN ,空间复杂度为 O(1)
//
// 事实上,我们可以用空间换时间来改善算法。将数域根据其值划分所属空间,使用 hash 表记录当前空间的一个值
// 在一次迭代所有值时,当前值可能:
// 1. 所属空间有值,返回 true
// 2. 所属上一个空间有值,两者差满足条件,返回 true
// 3. 所属下一个空间有值,两者差满足条件,返回 true
// 4. 将当前值记录到其空间中,同时维护窗口为大小 k:移动窗口并删除不在窗口内的值
//
//
// 算法时间复杂度 O(N),空间复杂度主要是 hash 表的大小:O(min(k,N))

impl Solution {
fn get_id(n: i64, w: i64) -> i32 {
if n >= 0 {
(n / w) as i32 //0~w-1 属于 0
} else {
((n + 1) / w - 1) as i32 //-w~-1 属于 -1
}
}
pub fn contains_nearby_almost_duplicate(nums: Vec<i32>, k: i32, t: i32) -> bool {
use std::collections::HashMap;
let mut buckets: HashMap<i32, i32> = HashMap::new();
let w: i64 = t as i64 + 1;
// 省略实现代码
false
}
}

#[cfg(test)]
mod tests {
use crate::array::contains_duplicate_iii::Solution;

#[test]
fn test() {
let nums = vec![2147483647, -1, 2147483647];
let k = 1;
let t = 2147483647;

let ans = Solution::contains_nearby_almost_duplicate(nums, k, t);
assert!(!ans)
}
}
```
Go 版本就是需要一个单独的文件夹(包),里面代码也差不多,包括实现代码和测试代码。

只要遵循特定语言的组织结构,测试规范,缝合其它语言进去也很容易。题目介绍、解题思路,可以放到代码里面,也可以单独用 markdown 文档记录,怎么顺手怎么来。
1  2  3  4  5  6  7  8  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2711 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 26ms · UTC 00:03 · PVG 08:03 · LAX 16:03 · JFK 19:03
Developed with CodeLauncher
♥ Do have faith in what you're doing.