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 :

Complex macros are used in C and Objective-C but have no counterpart in Swift. Complex macros are macros that do not define constants, including parenthesized, function-like macros. You use complex macros in C and Objective-C to avoid type-checking constraints or to avoid retyping large amounts of boilerplate code. However, macros can make debugging and refactoring difficult. In Swift, you can use functions and generics to achieve the same results without any compromises. Therefore, the complex macros that are in C and Objective-C source files are not made available to your Swift code.

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

最佳答案

据我所知,唉,Swift 多行字符串仍然不可用。但是,在对此进行一些研究时,我发现了一种可能有用的解决方法。它是这些项目的组合:

  • A Quick Hack to Quote Swift Strings in a Playground - 描述如何使服务替换和修复文本
  • pyrtsa 的评论,关于使用 "\n".join(...) 模拟多行字符串

设置自动化服务

使用Automator,您可以设置一个额外的服务,具有以下属性:

  • “运行 Shell 脚本”的单个 Action
  • 勾选“输出替换所选文本”
  • 将 shell 更改为 /usr/bin/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

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

  • 我使用 "\n".join(...) 版本来创建多行字符串,您可以使用 Swift - Split string over multiple lines 中的扩展答案,甚至是 + 变体,我将把它留给用户练习
  • 我选择了带空格的小缩进,并替换了 \" 使其更坚固
  • 注释当然是可选的,您可以稍微缩短代码。我试图选择清晰和可读性
  • 代码原样保留空格,但如果不需要,您可以进行编辑。也留给用户作为练习

服务的使用

打开您的 Playground 或代码编辑器,并插入/编写一些多行文本:

  • 标记文本 block
  • 执行 Xcode(或类似)> 服务 > 替换为带引号的 swift 多行连接

您现在有了一个正确快速编码的多行字符串。以下是文本前后的示例:

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

https://stackoverflow.com/questions/24312923/

相关文章:

objective-c - 最大 CGFloat 值是否有常数?

ios - UIButton 底部阴影

iphone - 如何将 nil 添加到 nsmutablearray?

ios - ld : file not found: linker command failed w

objective-c - 反转 NSString 文本

iphone - AdMob 崩溃并显示 [GADObjectPrivate changeState

iphone - 将数据传回前一个 View Controller

ios - command/usr/bin/codedesign 失败,退出代码 1-代码符号错误

objective-c - 将 UIColor 保存到 NSUserDefaults 并从中加载

iphone - HTML 内容适合 UIWebview 而无需缩小