循环遍历字符串列表 [英] Looping over a string list

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

问题描述

我想遍历字符串中给出的项目列表.根据 CMake 的要求,项目用分号分隔.以下

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

将字符串 "a;b;c" 解释为字符串文字.相反,当首先将 "a;b;c" 分配给变量时,一切都按预期进行.

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?

推荐答案

你困惑的根源可能是 CMake 对引用字符串的特殊解释.

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") [...]

(1)(2) 工作的原因见 CMake 的未引用参数的语言手册:

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.

请注意,这与引用参数不同,它也评估转义序列和变量引用,但不进行列表扩展.这解释了为什么 (4) 失败.

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.

现在有趣的问题是为什么 (3) 仍然成功.set 将接受单个值和列表值论据.事实上,结束 ) 或关键字之一 CACHEPARENT_SCOPE 之前的所有内容都被视为值的一部分.因此,以下两个命令是等效的:

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)

在这两种情况下,MYLIST 的值都是 a;b;c(不带引号).

In both cases the value of MYLIST will be a;b;c (without the quotes).

当我们现在将 ${MYLIST} 扩展为另一个命令时,您可以认为它使用 MYLIST 的值执行简单的字符串替换,即 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:

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

虽然这不会:

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

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

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