list 循环遍历字符串列表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24986392/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Looping over a string list
提问by Nico Schl?mer
I would like to loop over list of items, given in a string. As required by CMake, the items are separated by semicolons. The following
我想遍历字符串中给出的项目列表。根据 CMake 的要求,项目用分号分隔。下列
cmake_minimum_required(VERSION 2.8)
FOREACH(LETTER "a;b;c")
MESSAGE("<<${LETTER}>>")
ENDFOREACH()
interpretes the string "a;b;c"
as string literal. In contrast, when assigning "a;b;c"
to a variable first, all works out as expected.
将字符串解释"a;b;c"
为字符串文字。相反,当首先分配"a;b;c"
给变量时,一切都按预期进行。
cmake_minimum_required(VERSION 2.8)
SET(MYLIST "a;b;c")
FOREACH(LETTER ${MYLIST})
MESSAGE("<<${LETTER}>>")
ENDFOREACH()
Is this the recommended way for looping over a list or is there a more elegant solution?
这是循环列表的推荐方法还是有更优雅的解决方案?
回答by ComicSansMS
The source of your confusion is probably CMake's peculiar interpretation of quoted strings.
您困惑的根源可能是 CMake 对引用字符串的特殊解释。
For example, the following all iterate over the list of strings correctly:
例如,以下都正确地遍历字符串列表:
(1) foreach(LETTER a b c) [...]
(2) foreach(LETTER a;b;c) [...]
(3) set(MYLIST "a;b;c")
foreach(LETTER ${MYLIST}) [...]
The only case where this does not work is
这不起作用的唯一情况是
(4) foreach(LETTER "a;b;c") [...]
The reason why (1)
and (2)
work is found in CMake's language manual for unquoted arguments:
原因(1)
和(2)
工作可以在CMake 的语言手册中找到,用于未引用的参数:
Unquoted argument content consists of all text in a contiguous block of allowed or escaped characters. Both Escape Sequences and Variable References are evaluated. The resulting value is divided in the same way Lists divide into elements. Each non-empty element is given to the command invocation as an argument. Therefore an unquoted argument may be given to a command invocation as zero or more arguments.
未加引号的参数内容由允许或转义字符的连续块中的所有文本组成。转义序列和变量引用都被评估。结果值的划分方式与列表划分为元素的方式相同。每个非空元素都作为参数提供给命令调用。因此,可以将未加引号的参数作为零个或多个参数提供给命令调用。
Note that this is different from quoted arguments, which also evaluate Escape Sequences and Variable References, but do not do the list expansion. This explains why (4)
fails.
请注意,这与带引号的 arguments不同,后者也评估转义序列和变量引用,但不进行列表扩展。这解释了为什么(4)
失败。
The interesting question now is why (3)
still succeeds. set
will accept both single value and list value arguments. In fact, everything before the closing )
or one of the keywords CACHE
or PARENT_SCOPE
is considered part of the value. As such, the following two commands are equivalent:
现在有趣的问题是为什么(3)
仍然成功。set
将接受单值和列表值参数。事实上,关闭之前的所有内容)
或关键字之一CACHE
或都PARENT_SCOPE
被认为是值的一部分。因此,以下两个命令是等效的:
set(MYLIST "a;b;c")
set(MYLIST a;b;c)
In both cases the value of MYLIST
will be a;b;c
(without the quotes).
在这两种情况下,MYLIST
will的值都是a;b;c
(不带引号)。
When we now expand ${MYLIST}
into another command, you can think of it performing a simple string replacement with the value of MYLIST
, which is a;b;c
. The resulting command will then get expanded via the rules of of quoted or unquoted arguments. That is, the following will work:
当我们现在扩展${MYLIST}
到另一个命令时,您可以认为它使用 的值执行简单的字符串替换MYLIST
,即a;b;c
。结果命令将通过带引号或不带引号的参数规则进行扩展。也就是说,以下将起作用:
foreach(LETTER ${MYLIST}) [...]
while this will not:
虽然这不会:
foreach(LETTER "${MYLIST}") [...]