<p>In the syntax for the go programming language, you can write a switch statement to check the type of a variable with <strong>foo.(type)</strong>.
For example;</p>
<pre><code>err := foo()
switch err.(type) {
case *BadValueError:
// ...
}
</code></pre>
<p>This can be useful for checking an error's type, but, I don't understand why this syntax is restricted to only switch statements.
This would be super useful for if statements too.
An example of how it could be used;</p>
<pre><code>err := foo()
if err.(type) == *BadValueError {
// ...
}
</code></pre>
<p>The syntax above is not valid as using <strong>.(type)</strong> in an if statement will result in an error saying <strong>use of .(type) outside type switch</strong>.</p>
<p>In my opinion, it would be nice if <strong>.(type)</strong> could be used in an if statement. What are your thoughts?</p>
<hr/>**评论:**<br/><br/>bredov: <pre><p>You can do type assertion instead, like so</p>
<pre><code>err := foo()
if err, ok := err.(*BadValueError); ok {
// ...
}
</code></pre></pre>amenzhinsky: <pre><p>Just use type assertions:
_, ok := err.(*MyErr); ok</p></pre>epiris: <pre><p>There is only a left and right hand side for a condition, with the possible outcomes being equal or not equal. A type switch has many possible outcomes so it needed a separate syntax. So separating the value and the type with a operator makes it less clear in my opinion. Also since no assignment happens after how do you do work on the value? Would only cover cases you want to check the type but not use it.. not sure that ever happens.</p></pre>Acidic92: <pre><p>I am using an SSH package and I'm sending commands to a server and I want to check if the error is not nil, and if it's type of *ExitError. That's why I needed to check.</p></pre>TheMerovius: <pre><p>That is <em>exactly</em> what <code>if _, ok := err.(*FooError); ok {</code> does, in just 9 more characters than your proposal. Including the nil-check :)</p></pre>TheMerovius: <pre><p>Counterargument:</p>
<pre><code>x := foo()
if x.(bool) {
log.Printf("bool!")
}
</code></pre>
<p>would be ambiguous. Today, it says "assert that x is a bool, panic, if not. If that bool then is true, print something". You can't break that.</p>
<p>And given, that there's already a way to do what you want with just a handful of additional keystrokes, it doesn't seem worth it.</p></pre>jerf: <pre><p>The <code>switch</code> circumlocution avoids having to have types themselves being first-class citizens within the language, which comes with a host of implications, most of them contrary to Go's spirit of simplicity.</p>
<p>If you want to manipulate types directly, you can get types as values wrapped in Go objects from the <code>reflect</code> package, but be sure you need to before you do that. reflect isolates these concerns and keeps them out of the base language by wrapping them behind otherwise-normal Go objects, but this comes at a complexity price; you end up writing very detailed and verbose code to handle these cases.</p></pre>
