被 golang 坑了一下午, win 平台无法正常调用外部程序看这里。

2022-04-08 17:33:43 +08:00
 zeronofreya

很简单的调用:

cmd := exec.Command( "TeraCopy.exe", fmt.Sprintf(`*"%s" "%s"`, copyPaths, targetDir) )
err := cmd.Start()

报错:

---------------------------
 TeraCopy - Error
---------------------------
File not found:
\e:\**\tc.tmp \E:\**\b\
---------------------------
确定   
---------------------------

??? 啥玩意 ???

本着出了问题先找自身原因的混帐话优良传统,控制台与 TeraCopy 软件试了各种参数,都正常……

感觉是转义出了问题,谷歌了半天,除了复制粘贴就没别的了。

米田共里淘金终于发现了一片文章:Go 在 windows 上调用本地进程传参时的一个天坑

MD ,最终 tm 还是 go 的问题,一直不敢往那想,属实被喷怕了。 摘抄一下:

On Windows, processes receive the whole command line as a single string and do their own parsing. Command combines and quotes Args into a command line string with an algorithm compatible with applications using CommandLineToArgvW (which is the most common way). Notable exceptions are msiexec.exe and cmd.exe (and thus, all batch files), which have a different unquoting algorithm. In these or other similar cases, you can do the quoting yourself and provide the full command line in SysProcAttr.CmdLine, leaving Args empty.

反正我看不懂,看人家的解释:

也就是说,针对 cmd 参数加的引号参数会有不同的逻辑,必须在 SysProcAttr.CmdLine 中写入原始参数了,但是 Args 留空,又会导致 SysProcAttr 值为 nil ,所以简单赋值也是不行的

改了一下代码:

cmdLine := fmt.Sprintf(`copy *"%s" "%s"`, copyPaths, targetDir)
cmd := exec.Command("TeraCopy.exe")
cmd.SysProcAttr = &syscall.SysProcAttr{CmdLine: "/c " + cmdLine}
err := cmd.Start()

解决。

学习 go 一段时间,觉得它的开发者很矛盾,比如三元运算符,很多人都想要它,但官方却以语法统一、可能会导致阅读困难之类的理由推脱。 但

return r ? true : false

不比你 if 要整洁易读? 对多字节的处理也很费劲,我到现在不知道怎样查找某个中文的位置,IndexRune 报错,也没谷歌到答案

fmt.Println(strings.IndexRune("学习", "习"))


Error
./prog.go:9:42: cannot use "习" (untyped string constant) as rune value in argument to strings.IndexRune

是不是有人要说,爱用用,不用滚呢?

6430 次点击
所在节点    程序员
65 条回复
ec0
2022-04-08 18:57:18 +08:00
fmt.Println(strings.IndexRune("学习", '习')) 为什么返回的是 3 ,我以为是 1
KaynW
2022-04-08 18:59:48 +08:00
无力吐槽...
KaynW
2022-04-08 19:03:41 +08:00
@ec0 中文字符在 utf-8 下占 3 个字节
Tink
2022-04-08 19:04:22 +08:00
真的无力吐槽
Jarvis666
2022-04-08 19:22:26 +08:00
想黑 win ,又想黑 go ,又质疑人家跨平台开发的能力,啧啧
listenerri
2022-04-08 19:43:36 +08:00
“属实被喷怕了”

哈哈,建议 OP 慎重开喷,毕竟己不所欲勿施于人
deplivesb
2022-04-08 19:51:05 +08:00
又菜又爱吹
skiy
2022-04-08 20:56:45 +08:00
@0o0O0o0O0o rune 是 int32 的别名,这个有什么难理解的?换个名称也一样的使用方式。

rune is an alias for int32 and is equivalent to int32 in all ways.
https://github.com/golang/go/blob/5a90270d7f5b384de31399133c7336d007fbd93d/src/builtin/builtin.go#L92
0o0O0o0O0o
2022-04-08 21:28:26 +08:00
@skiy 是的,不难理解,猜测也是类似于别的语言里统计 UTF-8 字符数的方式,如我在#20 的自我批评,就是懒...
Vegetable
2022-04-08 21:37:07 +08:00
学而不思则罔,思而不学则殆。
我经常想发这句话,但是实际很少发。我觉得你很需要这句话。
hallDrawnel
2022-04-08 21:51:53 +08:00
第一个问题,把参数拆开成数组,交给基础库去完成拼接这才是跨平台的做法,你可以在 docker 、k8s 和各种 IDE 中发现都是这样输入的。

第二点是纯粹连编译错误都不看。

你要是喷在点上那肯定是大家跟着你一起喷,但这明显是你菜啊。
BeautifulSoap
2022-04-08 22:02:58 +08:00
其他不发表意见,但关于三元运算符我坚决站在 Go 这边

莫非定律了解下。只要语言给你用三元运算符,那绝对有程序员会拿它写出正常人没法轻松理解的代码。
比如每当看见 php 项目代码里有人把三元运算符玩出花的时候,我心里都是一万句草泥马
zeronofreya
2022-04-08 22:24:34 +08:00
@BeautifulSoap 那 goto 有何见解?
BeautifulSoap
2022-04-08 22:42:16 +08:00
@zeronofreya ?那还用问?当然是讨厌+反对 goto 咯,还有别的可能性?(当然 Go 一些功能你不用 goto 没法实现,有时候不得不捏着鼻子用)

所以,我一碗水端平了,你现在应该对于我坚决反对三元运算符没意见了吧?
skiy
2022-04-08 22:48:10 +08:00
你这知识面有点窄啊。。。

goto 是部分语言的一个特征。

C 语言的:
https://www.runoob.com/cprogramming/c-goto-statement.html

C++ 的:
https://www.runoob.com/cplusplus/cpp-goto-statement.html

C# 的:
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/statements/jump-statements#the-goto-statement

JAVA 虽然没有实现,但是保留了这个关键字。
BeautifulSoap
2022-04-08 22:57:07 +08:00
@zeronofreya 对了,有的东西你真要比烂的话我觉得三元运算符 100%是要比 goto 更烂的
比如 php 同时支持 goto 和三元运算符,但我 review 和参与的所有 php 项目没一个人在 php 中用过 goto ,而相应的在 php 中瞎几把乱用三元运算符的一大堆

比起 goto ,三元运算符是一个很容易让写代码的人产生迷之自信,让人有一种我写出的“简洁”代码很酷的错觉
liuzy1999
2022-04-08 23:00:57 +08:00
建议楼主加强英语能力与耐心,你会发现这些问题会改善很多的。
surbomfla
2022-04-08 23:13:08 +08:00
无论是百度还是必应 搜索 strings.IndexRune 都有正确的用法示例,op 是怎么找到 `[]rune(str)` 这种用法的?
Tink
2022-04-09 02:45:20 +08:00
你这个排错和搜索能力还需要提高
singerll
2022-04-09 06:04:36 +08:00
不是针对 go ,三元运算符你说易读我真的不认同。
还有第一个问题,本人非专业开发运维人员,偶尔写点小脚本,我用 python 的 subprocess 模块也有这个问题,第一次用也是调了好久,说白了就是懒得扒拉官方文档,随便搜个教程开始写,最后出问题排除就是比较麻烦。。。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/845764

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX