1

声明后如何访问 ProtoField 的 name 属性?

例如,类似于以下内容:

myproto = Proto("myproto", "我的原型")

myproto.fields.foo = ProtoField.int8("myproto.foo", "Foo", base.DEC)

打印(myproto.fields.foo.name)

我在哪里得到输出:

4

2 回答 2

1

另一种更简洁的方法:

local fieldString = tostring(field)
local i, j = string.find(fieldString, ": .* myproto")

print(string.sub(fieldString, i + 2, j - (1 + string.len("myproto")))

编辑:或者适用于任何协议的更简单的解决方案:

local fieldString = tostring(field)
local i, j = string.find(fieldString, ": .* ")

print(string.sub(fieldString, i + 2, j - 1))

当然,第二种方法只有在字段名称中没有空格的情况下才有效。由于情况不一定总是如此,因此第一种方法更稳健。这是包含在任何解析器都应该可用的函数中的第一个方法:

-- The field is the field whose name you want to print.
-- The proto is the name of the relevant protocol
function printFieldName(field, protoStr)

    local fieldString = tostring(field)
    local i, j = string.find(fieldString, ": .* " .. protoStr)

    print(string.sub(fieldString, i + 2, j - (1 + string.len(protoStr)))
end

...在这里它正在使用中:

printFieldName(myproto.fields.foo, "myproto")
printFieldName(someproto.fields.bar, "someproto")
于 2018-08-28T16:05:34.250 回答
0

好的,这很笨拙,当然不是“正确”的方法,但它似乎有效。

我在查看输出后发现了这一点

打印(tostring(myproto.fields.foo))

这似乎吐出了 ProtoField 的每个成员的值,但我无法弄清楚访问它们的正确方法。所以,相反,我决定解析字符串。此函数将返回“Foo”,但也可以调整为返回其他字段。

function getname(field) 

--First, convert the field into a string

--this is going to result in a long string with 
--a bunch of info we dont need

local fieldString= tostring(field)  
-- fieldString looks like:
-- ProtoField(188403): Foo  myproto.foo base.DEC 0000000000000000 00000000 (null) 

--Split the string on '.' characters
a,b=fieldString:match"([^.]*).(.*)" 
--Split the first half of the previous result (a) on ':' characters
a,b=a:match"([^.]*):(.*)"

--At this point, b will equal " Foo myproto" 
--and we want to strip out that abreviation "abvr" part

--Count the number of times spaces occur in the string
local spaceCount = select(2, string.gsub(b, " ", ""))

--Declare a counter
local counter = 0

--Declare the name we are going to return
local constructedName = ''

--Step though each word in (b) separated by spaces
for word in b:gmatch("%w+") do 
    --If we hav reached the last space, go ahead and return 
    if counter == spaceCount-1  then
        return constructedName
    end

    --Add the current word to our name 
    constructedName = constructedName .. word .. " "

    --Increment counter
    counter = counter+1
end
end 
于 2018-08-27T22:59:49.193 回答