如何在Swift中实现这个多行字符串文字宏?

时间:2014-06-19 17:34:36

标签: objective-c swift

在我的GPUImage框架的Objective-C代码中,我有以下宏:

#define STRINGIZE(x) #x
#define STRINGIZE2(x) STRINGIZE(x)
#define SHADER_STRING(text) @ STRINGIZE2(text)

允许我在我的自定义过滤器子类中将多行顶点和片段着色器内联为NSString文字,如下所示:

NSString *const kGPUImagePassthroughFragmentShaderString = SHADER_STRING
(
 varying highp vec2 textureCoordinate;

 uniform sampler2D inputImageTexture;

 void main()
 {
     gl_FragColor = texture2D(inputImageTexture, textureCoordinate);
 }
);

GPUImage需要这样才能提供包含在过滤器子类正文中的格式化顶点和片段着色器。将它们作为单独的文件运送会使框架无法编译到静态库中。使用上面的宏,我可以使这些着色器能够在框架代码和外部着色器文件之间进行复制和粘贴,而无需进行大量的重新格式化工作。

Swift取消了编译器宏和文档has this to say

  

复杂的宏用于C和Objective-C但没有对应的   在斯威夫特。复杂的宏是不定义常量的宏,   包括带括号的函数式宏。您使用复杂的宏   在C和Objective-C中避免类型检查约束或避免   重新输入大量的样板代码。但是,宏可以做   调试和重构很困难。在Swift中,您可以使用函数   和泛型,以达到相同的结果,没有任何妥协。   因此,C和Objective-C源代码中的复杂宏   您的Swift代码无法使用这些文件。

根据“在Swift中,您可以使用函数和泛型来实现相同的结果而不会有任何妥协”,Swift中是否有一种方法可以提供多行字符串文字而无需求助于一串串联操作?

2 个答案:

答案 0 :(得分:4)

据我所知,仍然没有Alas Swift多线串。然而,在对此进行一些研究时,我找到了一个可能有用的解决方法。它是这些项目的组合:

设置自动服务

使用 Automator ,您可以使用以下属性设置额外的服务

  • “运行Shell脚本”的单个操作
  • 勾选“输出替换所选文字”
  • 将shell更改为"\n".join(...)
  • 将以下代码摘录添加到操作窗口
  • 保存为“替换为引用的swift多行连接”

代码摘录

/usr/bin/perl

你当然可以自由使用你想要的shell和代码,我选择了perl,因为我很熟悉,这里有一些评论:

  • 我使用print "\"\\n\".join([\n"; # Start a join operation # For each line, reformat and print while(<>) { print " "; # A little indentation chomp; # Loose the newline s/([\\\"])/\\$1/g; # Replace \ and " with escaped variants print "\"$_\""; # Add quotes around the line print "," unless eof # Add a comma, unless it is the last line print "\n"; # End the line, preserving original line count } print " ])"; # Close the join operation 版本来创建多行字符串,您可以使用Swift - Split string over multiple lines的扩展答案,甚至是"\n".join(...)变体,我会将其作为练习用户
  • 我选择使用空格进行小缩进,并替换+\以使其更加坚固
  • 评论当然是可选的,您可能会稍微缩短代码。我试图选择清晰度和可读性
  • 代码按原样保留空格,但如果不需要则可以编辑。也留给用户练习

服务的使用

打开你的游乐场或代码编辑器,插入/写一些多行文字:

  • 标记文本块
  • 执行 Xcode(或类似)&gt;服务&gt;替换为引用的swift多行连接

现在你有一个适当快速编码的多行字符串。以下是文本之前和之后的示例:

"

答案 1 :(得分:-1)

看起来您的最终目标是避免包含独立着色器文件?

如果是这样,一种技术就是编写一个快速命令行实用程序,它生成一个字符串常量的.swift文件,表示某个文件夹中的着色器函数。

在项目中包含生成的.swift文件,并且没有运行时间损失,如果您很好地生成代码,甚至可以更轻松地进行调试。

可能需要不到一个小时,再也不需要为着色器使用宏。