Difference between `RawRepresentable<String>` and `LosslessStringConvertible`?

are RawRepresentable<String> and LosslessStringConvertible ever meant to be used together on the same type?

because i often add default implementations for my own string-schema protocols where Self:RawRepresentable<String> and Self:LosslessStringConvertible. but if a type conforms to both, then there is a witness ambiguity between the two default implementations.

LosslessStringConvertible refines CustomStringConvertible, which affects other things like calls to String(describing:). Semantically, LosslessStringConvertible means it can be represented as a string (e.g. an integer), while RawRepresentable<String> means it is a string underlyingly (e.g. an enum with raw type String).

2 Likes

aren’t these statements the same thing?

No, not at all. RawRepresentable<T> provides default implementations for other protocols that assume it is a T:

Using the raw value of a conforming type streamlines interoperation with Objective-C and legacy APIs and simplifies conformance to other protocols, such as Equatable, Comparable, and Hashable.

LosslessStringConvertible doesn't require that unequal strings produce unequal results. For example, "01" != "1", but Int("01") == Int("1"). Though RawRepresentable doesn't explicitly say that different raw values must produce different results, the default implementations certainly assume as much.

7 Likes

ah, that’s a great point