有没有人知道ruby解释器如何知道字符串文字(单引号字符串)和双引号字符串之间的区别?
我正在玩字符串,我正在试图弄清楚是否可以将它们从一个更改为另一个。
通过将字符串中的转义序列替换为各自的ascii代码,我能够在某种程度上做到这一点。
\n = 10 -> \\ = 92, n = 110
我拿了这个双引号字符串
"a\e[0;36m X \n"
当解释时会导致
a X
,X显示青色字体颜色。我将转义序列更改为前面带有反斜杠的字母。这仅在传递的字符串是双字符串时有效。我没有运气传递单引号字符串并将其更改为双引号,所以我可以允许插值。最后我还没有真正改变字符串的内容,所以它的行为就是这样。
现在让我有兴趣弄清楚ruby知道字符串是单引号还是双引号。我确信它有一个执行此操作的机制,因为当我在IRB中玩时,我做到了这一点。
a = "One\nTwo\t Half\n"
=> "One\nTwo\t Half\n"
b = 'Three \n Four \f Five'
=> "Three \\n Four \\f Five"
puts a + b
One
Two Half
Three \n Four \f Five
=> nil
c = a + b
One
Two Half
Three \n Four \f Five
=> nil
因此,你可以看到ruby足够聪明,可以记住字符串的某些块是单引号而其他字符串是双引号。我很想知道ruby是否保留了对原始字符串的引用/指针,并且当添加字符串时,它们只是链接在一起,因为它似乎不是在创建一个新的字符串。
我注意到的另一个奇怪的事情是没有办法从方法/函数返回字符串文字。如果有人能指出我的话。让我们留下另一个问题。
更新
我正在玩
ObjectSpace._id2ref(obj.object_id)
所以从上面的例子我尝试了这个。
a.object_id
=> 70219586904340
puts ObjectSpace._id2ref 70219586904340
One
Two Half
=> nil
b.object_id
=> 70219590675520
puts ObjectSpace._id2ref 70219590675520
Three \n Four \f Five
=> nil
c = a + b
puts ObjectSpace._id2ref c.object_id
One
Two Half
Three \n Four \f Five
=> nil
我现在正在播放这些对象,但我还没找到它。我想看到里面看到并看到objA + objB或那种程度的东西。
答案 0 :(得分:3)
没有区别,翻译方面。单引号和双引号字符串仅存在于解析器级别 1 。如果解析器遇到单引号,它会按字面解析字符:
import UIKit
extension UIApplication {
private struct AssociatedObjectsKeys {
static var visibleViewControllersPointers = "UIApplication_visibleViewControllersPointers"
}
fileprivate var visibleViewControllersPointers: NSPointerArray {
var pointers = objc_getAssociatedObject(self, &AssociatedObjectsKeys.visibleViewControllersPointers) as! NSPointerArray?
if (pointers == nil) {
pointers = NSPointerArray.weakObjects()
objc_setAssociatedObject(self, &AssociatedObjectsKeys.visibleViewControllersPointers, pointers, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
return pointers!
}
var visibleViewControllers: [UIViewController] {
return visibleViewControllersPointers.allObjects as! [UIViewController]
}
}
extension UIViewController {
private static func swizzleFunc(withOriginalSelector originalSelector: Selector, swizzledSelector: Selector) {
let originalMethod = class_getInstanceMethod(self, originalSelector)
let swizzledMethod = class_getInstanceMethod(self, swizzledSelector)
let didAddMethod = class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))
if didAddMethod {
class_replaceMethod(self, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}
override open class func initialize() {
if self != UIViewController.self {
return
}
let swizzlingClosure: () = {
UIViewController.swizzleFunc(withOriginalSelector: #selector(UIViewController.viewDidAppear(_:)),
swizzledSelector: #selector(uiapplication_visibleviewcontrollers_viewDidAppear(_:)))
UIViewController.swizzleFunc(withOriginalSelector: #selector(UIViewController.viewDidDisappear(_:)),
swizzledSelector: #selector(uiapplication_visibleviewcontrollers_viewDidDisappear(_:)))
}()
swizzlingClosure
}
@objc private func uiapplication_visibleviewcontrollers_viewDidAppear(_ animated: Bool) {
UIApplication.shared.visibleViewControllersPointers.addPointer(Unmanaged.passUnretained(self).toOpaque())
uiapplication_visibleviewcontrollers_viewDidAppear(animated)
}
@objc private func uiapplication_visibleviewcontrollers_viewDidDisappear(_ animated: Bool) {
let pointers = UIApplication.shared.visibleViewControllersPointers
for i in 0..<pointers.count {
if let pointer = pointers.pointer(at: i) {
let viewController = Unmanaged<AnyObject>.fromOpaque(pointer).takeUnretainedValue() as? UIViewController
if viewController.isEqual(self) {
pointers.removePointer(at: i)
break
}
}
}
uiapplication_visibleviewcontrollers_viewDidDisappear(animated)
}
}
如果解析器遇到双引号,它会将几个转义序列转换为它们各自的字符(例如,序列str = 'foo\nbar' #=> "foo\\nbar"
str.chars #=> ["f", "o", "o", "\\", "n", "b", "a", "r"]
str.codepoints #=> [102, 111, 111, 92, 110, 98, 97, 114]
转换为带有代码点10的ASCII字符,即换行符:
\n
您甚至可以混合使用单引号和双引号:
str = "foo\nbar" #=> "foo\nbar"
str.chars #=> ["f", "o", "o", "\n", "b", "a", "r"]
str.codepoints #=> [102, 111, 111, 10, 98, 97, 114]
解析器将其视为单个字符串文字str = 'foo' "\n" 'bar'
#=> "foo\nbar"
。
无论哪种方式,都没有“单引号字符串实例”和“双引号字符串实例”,只是字符串实例。
Ruby为您提供了几个文字来创建字符串("foo\nbar"
,'...'
,"..."
,%q{...}
,<<HEREDOC
)。结果对象都是一样的。
1 内部有静态字符串?...
和内插字符串NODE_STR
,但您无法从Ruby中访问该级别。一旦你有一个字符串实例,它只是一堆字符。
答案 1 :(得分:-1)
我注意到的另一个奇怪的事情是没有办法回归 方法/函数中的字符串文字。如果有人可以指出 我这个。
// create an extra class for the form to keep your controller clean
class UploadForm extends Form
{
public function __construct($controller, $name, $action)
{
$fields = FieldList::create(
TextField::create('Name', 'Name'),
UploadField::create('Upload', 'Upload')
);
$actions = FieldList::create(
FormAction::create($action, 'Submit')
->setAttribute('class', 'btn btn-success')
);
$validator = RequiredFields::create('Name');
parent::__construct($controller, $name, $fields, $actions, $validator);
}
}