V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  yicixin  ›  全部回复第 1 页 / 共 1 页
回复总数  5
不知道说的对不对,
1.首先看了下示例代码,一个 rule 是一个二维字符串数组,一段文本匹配该 rule 的条件是该文本中出现了 rule 中所有的关键词,既然如此,一个 rule 是否可以简化成一个一维字符串数组,即把二维数组中所有的关键词去重后放入一个一维数组,这样问题可以稍微简化一下。

2.接着,换个思路,把 10w 个 rule 中的所有关键词去重后构造前缀树,用 text 去进行匹配这个 10wKeyTrie ,拿到该 text 匹配到的所有关键词,将匹配到的所有关键词排序后拼接,最终得到一个字符串,例如 text 匹配了关键词 深灰色、锥形牛仔裤和 DIESEL ,假设排序拼接后是 DIESEL 深灰色锥形牛仔裤,记这个最终字符串为 matchText

3.上文说了把一个 rule 简化成一个一维字符串数组,那么每个 rule 也可以进行类似的排序拼接,那么最终 10w 个 rule 就是 10w 个字符串,把这 10w 个字符串构造前缀树,叫 10wRuleTrie 吧,最后用 2.中最后得到的 matchText 放进这个 10wRuleTrie 里进行匹配,如果成功匹配上即说明满足该条 rule 。

其中的 10wKeyTrie 和 10wRuleTrie 都是可以在初始化的时候就可以构造好,每次循环内要做的就是对进行 text 与 10wKeyTrie 的匹配-->得到多个关键词,排序后拼接--> 与 10wRuleTrie 进行匹配
308 天前
回复了 aababc 创建的主题 Go 编程语言 go 中关于 T 和 *T 方法集的一点疑问
所以 Go 对 T 的方法集自动生成*T 的包装方法,完全是给接口调用提供的。
基于这点,可以理解为什么 go 不允许你对一个方法同时实现 T 和*T 两份,是因为怕你两个实现的逻辑不一样。
308 天前
回复了 aababc 创建的主题 Go 编程语言 go 中关于 T 和 *T 方法集的一点疑问
@aababc 是的,因为在编译期,interface 调用方法并不知道实现者的具体类型,可能实现者是一个大对象,也可能是一个小对象,所占用的内存是确定不了的,这样就无法确定当前要分配的函数栈大小。实际在 go 中,interface 里装的是指向实现者的指针,指针的大小是确定的,就可以确定当前要分配的函数栈大小,相应的,只能调用*T 的方法集。
此时不能将指针解引用再调用 T 的方法集,因为解引用后要占用的内存大小是不确定的
308 天前
回复了 aababc 创建的主题 Go 编程语言 go 中关于 T 和 *T 方法集的一点疑问
是不是说反了,应该是 T 类型接收器的方法会在编译期间生成对应的*T 类型接收器的同名包装方法。

会不会在对应的*T 的包装方法中对原值产生影响,简单写一个测试就能知道,并不会影响,我猜测*T 包装方法内部可能是解引用再调用 T 的方法。

证明:
使用的代码:
package main

type entity struct {
data [2048]byte
v int
}

func (e entity) inc() {
e.v++
}

type incer interface {
inc()
}

func doSomething(i incer) {
i.inc()
}

func main() {
var e = entity{}
doSomething(&e)
}

1. 在 e.v++处设置断点,debug 运行可以断住,说明最终还是调用了 T 的方法
2. 断点时查看函数调用栈,对比 func (e entity) inc()和 func (e *entity) inc()


使用的代码:
package main

type entity struct {
data [2048]byte
v int
}

func (e entity) inc() {
e.v++
}

type incer interface {
inc()
}

func doSomething(i incer) {
i.inc()
}

func main() {
var e = entity{}
doSomething(&e)
}

1. 在 e.v++处设置断点,debug 运行可以断住,说明最终还是调用了 T 的方法
2. 断点时查看函数调用栈,对比 func (e entity) inc()和 func (e *entity) inc()
https://i.imgur.com/paLnYiL.png
可以发现在使用包装方法时的函数栈多出一层
就这个例子来讲,直接指针转换可以省去内存分配和拷贝,写法也更方便,但是要注意`juDianUpdateTeamReq`和`teamData `指向同一片内存了,它们是会相互影响的,小心不要出现内存竞争。
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4265 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 13ms · UTC 05:32 · PVG 13:32 · LAX 21:32 · JFK 00:32
Developed with CodeLauncher
♥ Do have faith in what you're doing.