- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
Xcode Refactor 有一个名为“转换为 Switch”的功能。我正在寻找可以由函数使用并转换为 switch 流语句的代码示例。
最佳答案
正如您所指出的,转换为 Switch
!= 转换为 Switch 语句
。为了理解其中的原因,我们需要了解 Xcode 重构功能在幕后是如何工作的。
我发现了什么:
这是一篇关于该主题的精彩文章: https://levelup.gitconnected.com/uncovering-xcode-indexing-8b3f3ff82551
它向我们指出了一个 swift
开源存储库:https://github.com/apple/swift
Xcode 重构是通过 SourceKit
框架完成的,该框架位于 swift 存储库内。
这是与 Xcode 通信的 SourceKit 协议(protocol):https://github.com/apple/swift/blob/main/tools/SourceKit/docs/Protocol.md
在内部,当我们选择“重构”时,Xcode会以某种方式(通过 XPC)发送某些内容,例如 source.request.workspace.refactoring
消息到 SourceKit。并且某处有一个“索引文件”,因此 SourceKit
可以立即(不是在 5 分钟内:))向您建议对于当前代码片段来说足够/可能的选项。
我已经从 github 加载了 swift
存储库(大约 30MB),导航到 SourceKit
代码并尝试查找与 source.request.workspace 相关的内容.重构
.
代码中的某处引用了 swift/IDE/RefactoringKinds.def
。我将复制粘贴此文件的内容:
#ifndef REFACTORING
#define REFACTORING(KIND, NAME, ID)
#endif
#ifndef SEMANTIC_REFACTORING
#define SEMANTIC_REFACTORING(KIND, NAME, ID) REFACTORING(KIND, NAME, ID)
#endif
#ifndef RANGE_REFACTORING
#define RANGE_REFACTORING(KIND, NAME, ID) SEMANTIC_REFACTORING(KIND, NAME, ID)
#endif
#ifndef INTERNAL_RANGE_REFACTORING
#define INTERNAL_RANGE_REFACTORING(KIND, NAME, ID) RANGE_REFACTORING(KIND, NAME, ID)
#endif
#ifndef CURSOR_REFACTORING
#define CURSOR_REFACTORING(KIND, NAME, ID) SEMANTIC_REFACTORING(KIND, NAME, ID)
#endif
/// Rename and categorise the symbol occurrences at provided locations
/// (syntactically).
REFACTORING(GlobalRename, "Global Rename", rename.global)
/// Categorize source ranges for symbol occurrences at provided locations
/// (syntactically).
REFACTORING(FindGlobalRenameRanges, "Find Global Rename Ranges", rename.global.find-ranges)
/// Find and categorize all occurences of the file-local symbol at a given
/// location.
REFACTORING(FindLocalRenameRanges, "Find Local Rename Ranges", rename.local.find-ranges)
/// Find and rename all occurences of the file-local symbol at a given
/// location.
CURSOR_REFACTORING(LocalRename, "Local Rename", rename.local)
CURSOR_REFACTORING(FillProtocolStub, "Add Missing Protocol Requirements", fillstub)
CURSOR_REFACTORING(ExpandDefault, "Expand Default", expand.default)
CURSOR_REFACTORING(ExpandSwitchCases, "Expand Switch Cases", expand.switch.cases)
CURSOR_REFACTORING(LocalizeString, "Localize String", localize.string)
CURSOR_REFACTORING(SimplifyNumberLiteral, "Simplify Long Number Literal", simplify.long.number.literal)
CURSOR_REFACTORING(CollapseNestedIfStmt, "Collapse Nested If Statements", collapse.nested.ifstmt)
CURSOR_REFACTORING(ConvertToDoCatch, "Convert To Do/Catch", convert.do.catch)
CURSOR_REFACTORING(TrailingClosure, "Convert To Trailing Closure", trailingclosure)
CURSOR_REFACTORING(MemberwiseInitLocalRefactoring, "Generate Memberwise Initializer", memberwise.init.local.refactoring)
CURSOR_REFACTORING(AddEquatableConformance, "Add Equatable Conformance", add.equatable.conformance)
CURSOR_REFACTORING(ConvertCallToAsyncAlternative, "Convert Call to Async Alternative", convert.call-to-async)
CURSOR_REFACTORING(ConvertToAsync, "Convert Function to Async", convert.func-to-async)
CURSOR_REFACTORING(AddAsyncAlternative, "Add Async Alternative", add.async-alternative)
RANGE_REFACTORING(ExtractExpr, "Extract Expression", extract.expr)
RANGE_REFACTORING(ExtractFunction, "Extract Method", extract.function)
RANGE_REFACTORING(ExtractRepeatedExpr, "Extract Repeated Expression", extract.expr.repeated)
RANGE_REFACTORING(MoveMembersToExtension, "Move To Extension", move.members.to.extension)
RANGE_REFACTORING(ConvertStringsConcatenationToInterpolation, "Convert to String Interpolation", convert.string-concatenation.interpolation)
RANGE_REFACTORING(ExpandTernaryExpr, "Expand Ternary Expression", expand.ternary.expr)
RANGE_REFACTORING(ConvertToTernaryExpr, "Convert To Ternary Expression", convert.ternary.expr)
RANGE_REFACTORING(ConvertIfLetExprToGuardExpr, "Convert To Guard Expression", convert.iflet.to.guard.expr)
RANGE_REFACTORING(ConvertGuardExprToIfLetExpr, "Convert To IfLet Expression", convert.to.iflet.expr)
RANGE_REFACTORING(ConvertToComputedProperty, "Convert To Computed Property", convert.to.computed.property)
RANGE_REFACTORING(ConvertToSwitchStmt, "Convert To Switch Statement", convert.switch.stmt)
// These internal refactorings are designed to be helpful for working on
// the compiler/standard library, etc., but are likely to be just confusing and
// noise for general development.
INTERNAL_RANGE_REFACTORING(ReplaceBodiesWithFatalError, "Replace Function Bodies With 'fatalError()'", replace.bodies.with.fatalError)
#undef CURSOR_REFACTORING
#undef INTERNAL_RANGE_REFACTORING
#undef RANGE_REFACTORING
#undef SEMANTIC_REFACTORING
#undef REFACTORING
如您所见,这里有Convert To Switch Statement
,以及Expand Switch Cases
,但没有Convert To Switch
。
所以我的猜测是,Xcode 在 UI 中向我们展示的内容要么是一个错误(他们忘记删除过时的内容),要么是当前版本的 Swift 存储库中不存在的某些实现的一部分。
无论如何,你可能会挖得更深 - 我只是试图在短时间内调查它。 :)如果你确实需要这样做,那么除了探索 SourceKit
协议(protocol)之外,我想你可以在 Github 上提出一个问题 - 也许那些知道的人会解释真正的原因。
让我们考虑这样一个例子:
enum SomeEnum {
case option1, option2, option3
}
func convertToSwitchExampleFunc(_ option: SomeEnum) {
if option == .option1 {
print("1")
}
if option == .option2 {
print("2")
}
if option == .option3 {
print("3")
}
}
func callingFunc() {
convertToSwitchExampleFunc(.option2)
}
如果您选择 convertToSwitchExampleFunc
主体内的所有代码,然后选择 Refactor
,Xcode 将不会向您显示“Convert to Switch”。
但是,如果您更改代码,使其更类似于丑陋的“switch”实现(if-else-if-else
链):
func convertToSwitchExampleFunc(_ option: SomeEnum) {
if option == .option1 {
print("1")
}
else if option == .option2 {
print("2")
}
else if option == .option3 {
print("3")
}
}
然后 Xcode 将向您显示“转换为 Switch 菜单”,自动重构的代码将如下所示:
func convertToSwitchExampleFunc(_ option: SomeEnum) {
switch option {
case .option1:
print("1")
case .option2:
print("2")
case .option3:
print("3")
default:
break
}
}
关于ios - Xcode 重构 "Convert to Switch",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67240530/
是否有使用 switch 语句检查数字 0-9 的简单方法?我正在编写一个程序来检查某些字符和数字。就像检查“\0”、“F”或“f”一样,想知道是否还有一种方法可以以类似的方式检查 0-9。我知道我可
我有一些数据需要转换,为此我需要一个超过 50 个案例的切换条件,我需要 3 次相同的案例,但在第三次我需要 50 个案例和一些更多,我不想写两次相同的代码。也许有可能做这样的事情。 switch (
我遇到这种情况,我必须检查两个 GET 变量。在检查语句内的第一个 switch 语句后,必须在第一个 case 循环内的第二个 switch 语句中检查第二个变量。 我无法在这里发布确切的代码,但这
如何使用函数指针代替 switch 语句? 最佳答案 与 ars 发布的链接略有不同的方法:您可以将 switch 语句中的值用作函数指针数组中的数组索引。所以不要写 switch (i) {
我必须评估很多条件。就我而言,我必须做这样的事情: switch(id) { case 5: // switch some other cases here case
switch 按钮位于 switch 语句内,但仅在 switch 语句外部时才有效这是我的代码:
我试图在 switch 语句中有一个 case 跳转到不同的 switch 语句。 在实践中,我希望用户在文本框中键入“关闭页面”,并且在浏览器关闭页面之前,我希望询问用户是否确定。输入“yes”将关
(引用java)我试图确定哪个更好,编写更多代码并可能节省一些计算时间,或者编写更少代码但可能牺牲一些计算时间。这就是我好奇的地方这样做会更有效率吗: switch (availability) {
我正在尝试构建一个 Android 应用程序,该应用程序可以访问加速度计传感器,并在单击按钮时将加速度计值(由 <> 包围)输出到串行 USB。当我更新值并尝试在 onClick 命令中调用它时遇到问
如何使用 Dwoo 模板引擎实现 switch case 语法。 最佳答案 {if 3 == 5} never gonna happen {elseif 3 == 3} if you don'
我想知道一个大的 switch 语句和几个小的 switch 语句之间是否有性能差异。 包含数百个案例的大型 switch 语句。 switch(quest){ case 1:
用户在 2 个选择框中进行选择后,我尝试计算出报值(value)。 看起来 1 需要 2 个 switch 语句。这可能吗? (可能的值比下面的值多得多。为了清楚起见,我删除了它们) var wor
我在主 while 循环内有一个开关,它将运行我的游戏。我正在尝试打破我的开关,以便转到不同的案例。下面的例子更好地解释了这一点: int j = 0; While(1){ switch(j){ ca
我用 Java 创建了一个菜单,其中每个选项都有另一个菜单。我想知道是否可以从内部菜单退出回到主菜单。 编辑:添加了主菜单选项 System.out.println("Main Menu");
我有一个计算新分数的方法。下面的方法有效,但问题是代码本身看起来可以被显着清理。我只是不知道什么是最好的方法。我根据 filterString 和枚举 individualScoreState 分配
在 Lisp 中使用字符串切换语句。 (defun switch(value) (case value (("XY") (print "XY"))
我想做这样的事情: int i = 0; switch(difficulty) { case 1: i++; break; case 2: i--; break; defaul
在 Obj-c 中,我做了一个 switch 语句,我曾经使用 UIsplitviewcontroller 在我的 iPad 应用程序中四处移动现在我想快速地做同样的事情……我试了几个小时,现在我唯一
我想写一个结构如下的报告: \begin{document} \input[option=a]{class} \input[option=b]{class} \in
我正在认真阅读 ngSwitch 的 AngularJS API 引用。当我谈到那部分时的指令: place an expression on the on="..." attribute (or t
我是一名优秀的程序员,十分优秀!