Swiftのprintの実装を確認
19170 ワード
public func print(
_ items: Any...,
separator: String = " ",
terminator: String = "\n"
) {
if let hook = _playgroundPrintHook {
var output = _TeeStream(left: "", right: _Stdout())
_print(items, separator: separator, terminator: terminator, to: &output)
hook(output.left)
}
else {
var output = _Stdout()
_print(items, separator: separator, terminator: terminator, to: &output)
}
}
internal func _print<Target: TextOutputStream>(
_ items: [Any],
separator: String = " ",
terminator: String = "\n",
to output: inout Target
) {
var prefix = ""
output._lock()
defer { output._unlock() }
for item in items {
output.write(prefix)
_print_unlocked(item, &output)
prefix = separator
}
output.write(terminator)
}
@usableFromInline
@_semantics("optimize.sil.specialize.generic.never")
internal func _print_unlocked<T, TargetStream: TextOutputStream>(
_ value: T, _ target: inout TargetStream
) {
// Optional has no representation suitable for display; therefore,
// values of optional type should be printed as a debug
// string. Check for Optional first, before checking protocol
// conformance below, because an Optional value is convertible to a
// protocol if its wrapped type conforms to that protocol.
// Note: _isOptional doesn't work here when T == Any, hence we
// use a more elaborate formulation:
if _openExistential(type(of: value as Any), do: _isOptional) {
let debugPrintable = value as! CustomDebugStringConvertible
debugPrintable.debugDescription.write(to: &target)
return
}
if let string = value as? String {
target.write(string)
return
}
if case let streamableObject as TextOutputStreamable = value {
streamableObject.write(to: &target)
return
}
if case let printableObject as CustomStringConvertible = value {
printableObject.description.write(to: &target)
return
}
if case let debugPrintableObject as CustomDebugStringConvertible = value {
debugPrintableObject.debugDescription.write(to: &target)
return
}
#if SWIFT_ENABLE_REFLECTION
let mirror = Mirror(reflecting: value)
_adHocPrint_unlocked(value, mirror, &target, isDebugPrint: false)
#else
target.write("(value cannot be printed without reflection)")
#endif
}
@_transparent
@_semantics("typechecker._openExistential(_:do:)")
public func _openExistential<ExistentialType, ContainedType, ResultType>(
_ existential: ExistentialType,
do body: (_ escapingClosure: ContainedType) throws -> ResultType
) rethrows -> ResultType {
// This implementation is never used, since calls to
// `Swift._openExistential(_:do:)` are resolved as a special case by
// the type checker.
Builtin.staticReport(_trueAfterDiagnostics(), true._value,
("internal consistency error: '_openExistential(_:do:)' operation failed to resolve"
as StaticString).utf8Start._rawValue)
Builtin.unreachable()
}
String
-
String.init<Subject>(describing:)
-
_print_unlocked
を呼んで、TextOutputStreamに自身を渡している。
-
public init<Subject>(describing instance: Subject) {
self.init()
_print_unlocked(instance, &self)
}
Author And Source
この問題について(Swiftのprintの実装を確認), 我々は、より多くの情報をここで見つけました https://zenn.dev/yusuga/articles/430144ebcd3229著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Collection and Share based on the CC protocol