6

Why in Swift is this legal...

assert( false, "Unexpected diagnosis: \(diagnosis)" );

whereas this is not?

let assertString = "Unexpected diagnosis: \(diagnosis)"
assert( false, assertString );

In the second snippet, I get the error...

Cannot invoke 'assert' with an argument list of type '(BooleanLiteralConvertible, String)

Surely, the second parameter is a string in both cases.

Pang
  • 9,564
  • 146
  • 81
  • 122
Fittoburst
  • 2,215
  • 2
  • 21
  • 33

2 Answers2

4

Second paramter of assert is declared as either message: @autoclosure () -> Str or _ message: StaticString. I guess "Unexpected diagnosis: \(diagnosis)" is treated as expression and picked up by @autoclosure, while assertString is simply a String variable that cannot be converted to closure or StaticString.

StaticString can be made only with:

static func convertFromExtendedGraphemeClusterLiteral(value: StaticString) -> StaticString
static func convertFromStringLiteral(value: StaticString) -> StaticString

I guess this explains why swift manual has note that you cannot use string interpolation in assert() as there is no support for StringInterpolationConvertible.

Kirsteins
  • 27,065
  • 8
  • 76
  • 78
  • Wow! Thanks that's pretty heavy going for someone with < 24 hours experience in Swift. I guess it's side-effect of years of working in the 'pointer' world that this wasn't obvious to me. Took some reading, by I understand it now. Thanks – Fittoburst Oct 01 '14 at 10:02
0

quote form documentations:

...(assert()) Performs a traditional C-style assert with an optional message. Use this function for internal sanity checks that are active during testing but do not impact performance of shipping code. To check for invalid usage in Release builds, see precondition(_:_:file:line:).

and i tested on Xcode 8, precondition(_:_:file:line:) works fine with formatted strings. e.g.:

precondition(userId.lengthOfBytes(using: .ascii) > 0, "\(userId) is invalid for DBManager.id")
wzso
  • 3,482
  • 5
  • 27
  • 48