在字符串列表上循环 [英] Looping over a string list

查看:174
本文介绍了在字符串列表上循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想循环列表的项目,给出一个字符串。根据CMake的要求,项目由分号分隔。以下

  cmake_minimum_required(VERSION 2.8)

FOREACH(LETTERa; b; c)
MESSAGE(< <$ {LETTER}>>)
ENDFOREACH()

将字符串解释为字符串字面值a; b; c。相反,当首先将a; b; c分配给变量时,所有都会按预期。

  cmake_minimum_required(VERSION 2.8)

SET(MYLISTa; b; c)
FOREACH(LETTER $ {MYLIST})
MESSAGE(< <$ {LETTER}>>)
ENDFOREACH()

这是循环列表的推荐方式,还是有更优雅的解决方案?

解决方案

混淆可能是CMake对引用字符串的特殊解释。



例如,下面的所有内容都正确地遍历字符串列表:



...
(2)foreach(LETTER a; b; c)(...)
(3)set(MYLISTa; b; c)
foreach(LETTER $ {MYLIST})[...]

这不能工作的唯一情况是

 (4)foreach a; b; c)[...] 



< >(1)和(2)工作发现于关于无参考参数的PHP语言手册


无引号参数内容由允许或转义字符的连续块
中的所有文本组成。转义序列和变量
引用被计算。结果值划分为相同的
方式列表划分为元素
。每个非空元素作为参数提供给
命令调用。因此,一个无引号的参数可以将
作为零个或多个参数赋予命令调用。


请注意, 引用的参数,它们还会计算转义序列和变量引用,但不做列表扩展。这就解释了为什么(4)失败。



现在有趣的问题是为什么仍然成功。 设置 将接受单值和列表值参数。事实上,关闭之前的一切或关键字 CACHE PARENT_SCOPE 被认为是值的一部分。因此,以下两个命令是等效的:

  set(MYLISTa; b; c)
set (MYLIST a; b; c)

在这两种情况下, MYLIST 将为 a; b; c (不含引号)。



现在将 $ {MYLIST} 展开到另一个命令中,您可以认为它使用 MYLIST a; b; c 。生成的命令将通过引用或无引用参数的规则扩展。也就是说,以下将工作:

  foreach(LETTER $ {MYLIST})[...] 

,但这不会:

  foreach(LETTER$ {MYLIST})[...] 


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_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.

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?

解决方案

The source of your confusion is probably CMake's peculiar interpretation of quoted strings.

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:

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.

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:

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).

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:

foreach(LETTER ${MYLIST}) [...]

while this will not:

foreach(LETTER "${MYLIST}") [...]

这篇关于在字符串列表上循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆