你怎么能在Swift中实现这个多行stringmacros?

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

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

这使我可以在我的自定义filter子类中内联多行顶点和片段着色器作为NSString文字,如下所示:

 NSString *const kGPUImagePassthroughFragmentShaderString = SHADER_STRING ( varying highp vec2 textureCoordinate; uniform sampler2D inputImageTexture; void main() { gl_FragColor = texture2D(inputImageTexture, textureCoordinate); } ); 

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

Swift不使用编译器macros,文档有这样的说法 :

在C和Objective-C中使用复杂的macros,但在Swift中没有对应的macros。 复杂的macros是不定义常量的macros,包括括起来的函数式macros。 你在C和Objective-C中使用复杂的macros来避免types检查约束,或者避免重新input大量的样板代码。 但是,macros可能会使debugging和重构变得困难。 在Swift中,您可以使用函数和generics来获得相同的结果,而不会有任何妥协。 因此,C和Objective-C源文件中的复杂macros不能用于Swift代码。

每行“在Swift中,你可以使用函数和generics来实现相同的结果,而不会有任何妥协”,有没有一种方法在Swift中提供多行string文字,而不诉诸串联操作的string?

据我所知,唉Swift多行string仍然不可用。 但是,在做这方面的一些研究时,我发现了一个可能有用的解决方法。 这是这些项目的组合:

  • 在游乐场引用Swiftstring的快速入侵 – 描述如何使服务replace和修复文本
  • pyrtsa的评论,关于使用"\n".join(...)来模拟多行string

设置一个自动服务

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

  • “运行Shell脚本”
  • 勾选“输出replace选定的文本”
  • 将shell更改为/usr/bin/perl
  • 将下面的代码摘录添加到操作窗口中
  • 保存为“replace为引用的swift多行join”

代码摘录

 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 

你当然可以自由地使用你想要的任何shell和代码,我selectperl,因为这是我熟悉的,这里有一些评论:

  • 我使用"\n".join(...)版本来创build多行string,你可以使用Swift的扩展答案- 分割string在多行 ,甚至是+变体,我会把它作为一个练习为用户
  • 我select了一些有空格的缩进,取而代之的是"使之更坚固”
  • 评论当然是可选的,你可能会稍微缩短代码。 我试图select清晰和可读性
  • 代码保留空格,但是如果不需要,可以编辑它。 也留给用户练习

服务的使用

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

  • 标记文本块
  • 执行Xcode(或类似)>服务>用引用的swift多行joinreplace

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

 Here is my multiline text example with both a " and a \ within the text "\n".join([ "Here is my multiline text ", "example with both a \" and", "a \\ within the text" ]) 

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

如果是这样,一种技术是编写一个快速的命令行实用程序,该实用程序会生成一个表示特定文件夹中的着色器函数的string常量的.swift文件。

将生成的.swift文件包含在您的项目中,如果您很好地生成代码,则不会有运行时间的损失,甚至更容易进行debugging。

可能需要不到一个小时,再也不需要macros着色器。