如何在Swift中实现此多行字符串文字宏? [英] How can you implement this multiline string literal macro in Swift?

查看:126
本文介绍了如何在Swift中实现此多行字符串文字宏?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In my Objective-C code for my GPUImage framework, I have the following macro:

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

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

which allows me to inline multiline vertex and fragment shaders as NSString literals within my custom filter subclasses, like this:

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

 uniform sampler2D inputImageTexture;

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

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

GPUImage needs this in order to provide formatted vertex and fragment shaders that are included in the body text of filter subclasses. Shipping them as separate files would make the framework unable to be compiled into a static library. Using the above macro, I can make these shaders able to be copied and pasted between the framework code and external shader files without a ridiculous amount of reformatting work.

Swift取消了编译器宏和文档

Swift does away with compiler macros, and the documentation has this to say:

复杂宏用于C和Objective-C,但没有对应的宏 在Swift中.复杂宏是不定义常量的宏, 包括带括号的,类似于函数的宏.您使用复杂的宏 在C和Objective-C中避免类型检查约束或避免 重新键入大量样板代码.但是,宏可以使 调试和重构困难.在Swift中,您可以使用函数 和泛型实现相同的结果而没有任何妥协. 因此,C和Objective-C源代码中的复杂宏 文件无法用于您的Swift代码.

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中,有没有一种方法可以提供多行字符串文字而无需借助串联操作字符串?

Per the line "In Swift, you can use functions and generics to achieve the same results without any compromises", is there a way in Swift to provide multiline string literals without resorting to a string of concatenation operations?

推荐答案

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

Alas Swift multiline strings are still not available, as far as I know. However when doing some research regarding this, I found a workaround which could be useful. It is a combination of these items:

  • A Quick Hack to Quote Swift Strings in a Playground - Describing how to make an service replacing and fixing texts
  • The comment by pyrtsa, regarding using "\n".join(...) to emulate the multiline strings

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

Using Automator you could set up an extra service with the following properties:

  • 运行Shell脚本"的单个操作
  • 勾选输出替换选定的文本"
  • 将shell更改为/usr/bin/perl
  • 将下面的代码摘录添加到操作窗口中
  • 另存为用带引号的快速多行连接替换"
  • A single action of "Run Shell Script"
  • Tick off the "Output replaces selected text"
  • Change shell to /usr/bin/perl
  • Add the code excerpt below to the action window
  • Save as something like "Replace with quoted swift multiline 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和代码,我选择Perl是我熟悉的,下面是一些注释:

You are of course free to use whatever shell and code you want, I chose perl as that is familiar to me, and here are some comments:

  • I used the "\n".join(...) version to create the multiline string, you could use the extension answer from Swift - Split string over multiple lines, or even the + variant, I'll leave that as an exercise for the user
  • I opted for a little indentation with spaces, and to replace the \ and " to make it a little sturdier
  • Comments are of course optional, and you could probably shorten the code somewhat. I tried to opt for clarity and readability
  • The code, as is, preserves spaces, but you could be edited if that is not wanted. Also left as an exercise for the user

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

Open up your playground or code editor, and insert/write some multline text:

  • 标记文本块
  • 执行 Xcode(或类似代码)>服务>替换为带引号的快速多行联接

您现在可以使用正确的快速编码来创建多行字符串.这是文本前后的示例:

You now have a multiline string in proper swift coding. Here are an example of before and after text:

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

这篇关于如何在Swift中实现此多行字符串文字宏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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