{"id":1057,"date":"2026-08-16T19:31:56","date_gmt":"2026-08-16T19:31:56","guid":{"rendered":"https:\/\/www.devopsschool.com\/tutorials\/?p=1057"},"modified":"2026-08-16T19:31:57","modified_gmt":"2026-08-16T19:31:57","slug":"go-tutorials-go-type-assertions-easy-basic-to-advanced","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/tutorials\/go-tutorials-go-type-assertions-easy-basic-to-advanced\/","title":{"rendered":"Go Tutorials: Go Type Assertions \u2014 Easy Basic to Advanced"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">1. What Is a Type Assertion?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A <strong>type assertion<\/strong> is used when you have a value stored inside an <strong>interface<\/strong> and you want to check or retrieve its real type.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The syntax is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>value.(Type)\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Easy meaning:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\"Is the value inside this interface really this Type?\"\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">2. Simplest Example<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>package main\n\nimport \"fmt\"\n\nfunc main() {\n\n\t\/\/ 'value' has type 'any'.\n\t\/\/\n\t\/\/ any can hold values of different types.\n\tvar value any\n\n\t\/\/ Store a string inside 'value'.\n\tvalue = \"Hello Go\"\n\n\t\/\/ Type assertion:\n\t\/\/\n\t\/\/ value.(string)\n\t\/\/\n\t\/\/ means:\n\t\/\/\n\t\/\/ \"I expect the value stored inside\n\t\/\/ this interface to be a string.\"\n\ttext := value.(string)\n\n\t\/\/ 'text' is now a normal string variable.\n\tfmt.Println(text)\n\n\t\/\/ Output:\n\t\/\/\n\t\/\/ Hello Go\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The important line is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>text := value.(string)\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Think of it as:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>value contains something\n        \u2193\nvalue.(string)\n        \u2193\n\"Is that something a string?\"\n        \u2193\nYes \u2192 give me the string\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">3. Why Do We Need Type Assertions?<\/h1>\n\n\n\n<pre class=\"wp-block-code\"><code>package main\n\nimport \"fmt\"\n\nfunc main() {\n\n\t\/\/ Normal string variable.\n\tname := \"Alice\"\n\n\t\/\/ Go already knows 'name' is a string.\n\t\/\/ Therefore no type assertion is needed.\n\tfmt.Println(len(name))\n\n\t\/\/ --------------------------------\n\n\t\/\/ Here the variable type is 'any'.\n\tvar value any = \"Alice\"\n\n\t\/\/ Go knows that 'value' is an interface,\n\t\/\/ but we want to work with the string\n\t\/\/ stored inside it.\n\n\t\/\/ Extract the string.\n\ttext := value.(string)\n\n\t\/\/ Now text is a normal string.\n\tfmt.Println(len(text))\n\n\t\/\/ Output:\n\t\/\/\n\t\/\/ 5\n\t\/\/ 5\n}\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">4. Think of an Interface as a Box<\/h1>\n\n\n\n<pre class=\"wp-block-code\"><code>package main\n\nimport \"fmt\"\n\nfunc main() {\n\n\t\/\/ Imagine 'value' as a box.\n\t\/\/\n\t\/\/ +----------------------+\n\t\/\/ | Type:  string        |\n\t\/\/ | Value: \"Go\"          |\n\t\/\/ +----------------------+\n\n\tvar value any = \"Go\"\n\n\t\/\/ Type assertion asks:\n\t\/\/\n\t\/\/ \"Does this box contain a string?\"\n\ttext := value.(string)\n\n\t\/\/ Yes.\n\t\/\/ Therefore Go gives us the string.\n\tfmt.Println(text)\n\n\t\/\/ Output:\n\t\/\/\n\t\/\/ Go\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is the easiest mental model:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Interface = Box\n\nType assertion = Check what is inside the box\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">5. What Happens If the Type Is Wrong?<\/h1>\n\n\n\n<pre class=\"wp-block-code\"><code>package main\n\nfunc main() {\n\n\t\/\/ The real value stored here is an int.\n\tvar value any = 100\n\n\t\/\/ This would cause a runtime PANIC:\n\t\/\/\n\t\/\/ text := value.(string)\n\t\/\/\n\t\/\/ Why?\n\t\/\/\n\t\/\/ Actual stored type:\n\t\/\/\n\t\/\/ int\n\t\/\/\n\t\/\/ Requested type:\n\t\/\/\n\t\/\/ string\n\t\/\/\n\t\/\/ We told Go:\n\t\/\/\n\t\/\/ \"I am sure this is a string.\"\n\t\/\/\n\t\/\/ But it is not.\n\n\t_ = value\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">So this form:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>text := value.(string)\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">means:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\"I am certain this is a string.\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If you are wrong, the program can panic.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">6. Safe Type Assertion<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">This is the form you should learn first.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package main\n\nimport \"fmt\"\n\nfunc main() {\n\n\tvar value any = \"Hello\"\n\n\t\/\/ Safe type assertion returns TWO values.\n\t\/\/\n\t\/\/ text = extracted string\n\t\/\/ ok   = whether the assertion succeeded\n\ttext, ok := value.(string)\n\n\t\/\/ Check if the assertion failed.\n\tif !ok {\n\t\tfmt.Println(\"Value is not a string\")\n\t\treturn\n\t}\n\n\t\/\/ If we reach this line,\n\t\/\/ 'text' is definitely a string.\n\tfmt.Println(text)\n\n\t\/\/ Output:\n\t\/\/\n\t\/\/ Hello\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Remember this pattern:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>value, ok := interfaceValue.(Type)\n\nif !ok {\n\t\/\/ wrong type\n\treturn\n}\n\n\/\/ safely use value\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">7. What Does <code>ok<\/code> Mean?<\/h1>\n\n\n\n<pre class=\"wp-block-code\"><code>package main\n\nimport \"fmt\"\n\nfunc main() {\n\n\tvar value any = \"Go\"\n\n\ttext, ok := value.(string)\n\n\t\/\/ Because value contains a string:\n\t\/\/\n\t\/\/ text = \"Go\"\n\t\/\/ ok   = true\n\n\tfmt.Println(text)\n\tfmt.Println(ok)\n\n\t\/\/ Output:\n\t\/\/\n\t\/\/ Go\n\t\/\/ true\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If it fails:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package main\n\nimport \"fmt\"\n\nfunc main() {\n\n\tvar value any = 100\n\n\ttext, ok := value.(string)\n\n\t\/\/ value contains int,\n\t\/\/ not string.\n\t\/\/\n\t\/\/ Therefore:\n\t\/\/\n\t\/\/ text = \"\"\n\t\/\/\n\t\/\/ \"\" is the zero value of string.\n\t\/\/\n\t\/\/ ok = false\n\n\tfmt.Printf(\"text = %q\\n\", text)\n\tfmt.Println(\"ok =\", ok)\n\n\t\/\/ Output:\n\t\/\/\n\t\/\/ text = \"\"\n\t\/\/ ok = false\n}\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">8. Type Assertion with <code>int<\/code><\/h1>\n\n\n\n<pre class=\"wp-block-code\"><code>package main\n\nimport \"fmt\"\n\nfunc main() {\n\n\t\/\/ Store an integer inside an interface.\n\tvar value any = 25\n\n\t\/\/ Try to extract an int.\n\tnumber, ok := value.(int)\n\n\tif !ok {\n\t\tfmt.Println(\"Not an integer\")\n\t\treturn\n\t}\n\n\t\/\/ number is now a normal int.\n\tresult := number * 2\n\n\tfmt.Println(result)\n\n\t\/\/ Output:\n\t\/\/\n\t\/\/ 50\n}\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">9. Type Assertion with a Struct<\/h1>\n\n\n\n<pre class=\"wp-block-code\"><code>package main\n\nimport \"fmt\"\n\n\/\/ Normal struct.\ntype User struct {\n\tName string\n\tAge  int\n}\n\nfunc main() {\n\n\t\/\/ Store a User inside 'any'.\n\tvar value any = User{\n\t\tName: \"Alice\",\n\t\tAge:  30,\n\t}\n\n\t\/\/ Extract User from the interface.\n\tuser, ok := value.(User)\n\n\tif !ok {\n\t\tfmt.Println(\"Value is not a User\")\n\t\treturn\n\t}\n\n\t\/\/ 'user' is now type User,\n\t\/\/ so its fields are available.\n\tfmt.Println(user.Name)\n\tfmt.Println(user.Age)\n\n\t\/\/ Output:\n\t\/\/\n\t\/\/ Alice\n\t\/\/ 30\n}\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">10. Important: <code>User<\/code> and <code>*User<\/code> Are Different<\/h1>\n\n\n\n<pre class=\"wp-block-code\"><code>package main\n\nimport \"fmt\"\n\ntype User struct {\n\tName string\n}\n\nfunc main() {\n\n\t\/\/ Store a POINTER to User.\n\tvar value any = &amp;User{\n\t\tName: \"Alice\",\n\t}\n\n\t\/\/ This checks for User.\n\t\/\/\n\t\/\/ But the stored type is *User.\n\tuser1, ok1 := value.(User)\n\n\tfmt.Println(ok1)\n\n\t\/\/ Output:\n\t\/\/\n\t\/\/ false\n\n\t_ = user1\n\n\t\/\/ --------------------------------\n\n\t\/\/ This checks for *User.\n\t\/\/\n\t\/\/ That matches the actual stored type.\n\tuser2, ok2 := value.(*User)\n\n\tfmt.Println(ok2)\n\tfmt.Println(user2.Name)\n\n\t\/\/ Output:\n\t\/\/\n\t\/\/ true\n\t\/\/ Alice\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Remember:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>User\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">and:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>*User\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">are different types.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">11. Type Assertion Does NOT Convert Types<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">This is extremely important.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package main\n\nimport \"fmt\"\n\nfunc main() {\n\n\t\/\/ The actual stored type is float64.\n\tvar value any = 10.5\n\n\t\/\/ We ask:\n\t\/\/\n\t\/\/ \"Is the stored value an int?\"\n\tnumber, ok := value.(int)\n\n\t\/\/ No.\n\tfmt.Println(number)\n\tfmt.Println(ok)\n\n\t\/\/ Output:\n\t\/\/\n\t\/\/ 0\n\t\/\/ false\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Type assertion does <strong>not<\/strong> mean:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Convert float64 to int\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">It means:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Check whether the value is already an int\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">To convert:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package main\n\nimport \"fmt\"\n\nfunc main() {\n\n\tvar value any = 10.5\n\n\t\/\/ Step 1:\n\t\/\/ Assert the REAL stored type.\n\tdecimal, ok := value.(float64)\n\n\tif !ok {\n\t\treturn\n\t}\n\n\t\/\/ Step 2:\n\t\/\/ Perform normal type conversion.\n\tnumber := int(decimal)\n\n\tfmt.Println(number)\n\n\t\/\/ Output:\n\t\/\/\n\t\/\/ 10\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">So:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>value.(float64)\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">is a <strong>type assertion<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int(decimal)\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">is a <strong>type conversion<\/strong>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">12. Type Assertion vs Type Conversion<\/h1>\n\n\n\n<pre class=\"wp-block-code\"><code>package main\n\nfunc main() {\n\n\t\/\/ --------------------------\n\t\/\/ TYPE CONVERSION\n\t\/\/ --------------------------\n\n\tnumber := 10\n\n\t\/\/ Convert int into float64.\n\tdecimal := float64(number)\n\n\t_ = decimal\n\n\t\/\/ --------------------------\n\t\/\/ TYPE ASSERTION\n\t\/\/ --------------------------\n\n\tvar value any = \"Go\"\n\n\t\/\/ Extract\/check the string already\n\t\/\/ stored inside the interface.\n\ttext := value.(string)\n\n\t_ = text\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Remember:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Type Conversion\n---------------\n\nint \u2192 float64\n\nfloat64(number)\n\n\nType Assertion\n--------------\n\ninterface \u2192 contained type\n\nvalue.(string)\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">13. Real Use Case: <code>map[string]any<\/code><\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">You may see dynamic data written like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package main\n\nimport \"fmt\"\n\nfunc main() {\n\n\t\/\/ Values can contain different types.\n\tdata := map&#91;string]any{\n\t\t\"name\": \"Alice\",\n\t\t\"age\":  30,\n\t}\n\n\t\/\/ data&#91;\"name\"] returns an 'any' value.\n\tnameValue := data&#91;\"name\"]\n\n\t\/\/ Extract string.\n\tname, ok := nameValue.(string)\n\n\tif !ok {\n\t\tfmt.Println(\"name is not a string\")\n\t\treturn\n\t}\n\n\t\/\/ Extract age.\n\tageValue := data&#91;\"age\"]\n\n\tage, ok := ageValue.(int)\n\n\tif !ok {\n\t\tfmt.Println(\"age is not an integer\")\n\t\treturn\n\t}\n\n\tfmt.Println(\"Name:\", name)\n\tfmt.Println(\"Age:\", age)\n\n\t\/\/ Output:\n\t\/\/\n\t\/\/ Name: Alice\n\t\/\/ Age: 30\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is one common use case for type assertions.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">14. Checking Multiple Possible Types<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">You could do this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package main\n\nimport \"fmt\"\n\nfunc printValue(value any) {\n\n\t\/\/ Check string.\n\tif text, ok := value.(string); ok {\n\t\tfmt.Println(\"String:\", text)\n\t\treturn\n\t}\n\n\t\/\/ Check int.\n\tif number, ok := value.(int); ok {\n\t\tfmt.Println(\"Integer:\", number)\n\t\treturn\n\t}\n\n\t\/\/ Check bool.\n\tif flag, ok := value.(bool); ok {\n\t\tfmt.Println(\"Boolean:\", flag)\n\t\treturn\n\t}\n\n\tfmt.Println(\"Unknown type\")\n}\n\nfunc main() {\n\n\tprintValue(\"Go\")\n\tprintValue(100)\n\tprintValue(true)\n\n\t\/\/ Output:\n\t\/\/\n\t\/\/ String: Go\n\t\/\/ Integer: 100\n\t\/\/ Boolean: true\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This works.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But when many types are possible, use a <strong>type switch<\/strong>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">15. Type Switch<\/h1>\n\n\n\n<pre class=\"wp-block-code\"><code>package main\n\nimport \"fmt\"\n\nfunc printValue(value any) {\n\n\t\/\/ value.(type) checks the concrete type\n\t\/\/ stored inside the interface.\n\tswitch v := value.(type) {\n\n\tcase string:\n\n\t\t\/\/ Here v is a string.\n\t\tfmt.Println(\"String:\", v)\n\n\tcase int:\n\n\t\t\/\/ Here v is an int.\n\t\tfmt.Println(\"Integer:\", v)\n\n\tcase bool:\n\n\t\t\/\/ Here v is a bool.\n\t\tfmt.Println(\"Boolean:\", v)\n\n\tcase float64:\n\n\t\t\/\/ Here v is a float64.\n\t\tfmt.Println(\"Float:\", v)\n\n\tdefault:\n\n\t\tfmt.Println(\"Unknown type\")\n\t}\n}\n\nfunc main() {\n\n\tprintValue(\"Go\")\n\tprintValue(100)\n\tprintValue(true)\n\tprintValue(3.14)\n\n\t\/\/ Output:\n\t\/\/\n\t\/\/ String: Go\n\t\/\/ Integer: 100\n\t\/\/ Boolean: true\n\t\/\/ Float: 3.14\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Simple rule:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>One possible type\n-----------------\n\nvalue, ok := data.(string)\n\n\nMany possible types\n-------------------\n\nswitch v := data.(type)\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">16. Type Assertion with Interfaces<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Type assertions can also check whether a value supports another interface.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package main\n\nimport \"fmt\"\n\n\/\/ Every Speaker can Speak().\ntype Speaker interface {\n\tSpeak()\n}\n\n\/\/ Every Runner can Run().\ntype Runner interface {\n\tRun()\n}\n\ntype Dog struct{}\n\nfunc (Dog) Speak() {\n\tfmt.Println(\"Woof!\")\n}\n\nfunc (Dog) Run() {\n\tfmt.Println(\"Dog is running\")\n}\n\nfunc main() {\n\n\t\/\/ Variable only promises Speaker behavior.\n\tvar speaker Speaker = Dog{}\n\n\tspeaker.Speak()\n\n\t\/\/ Now ask:\n\t\/\/\n\t\/\/ \"Does the actual value inside speaker\n\t\/\/ also satisfy Runner?\"\n\trunner, ok := speaker.(Runner)\n\n\tif !ok {\n\t\tfmt.Println(\"Cannot run\")\n\t\treturn\n\t}\n\n\t\/\/ Yes, Dog also has Run().\n\trunner.Run()\n\n\t\/\/ Output:\n\t\/\/\n\t\/\/ Woof!\n\t\/\/ Dog is running\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is a very useful advanced use case.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">17. Practical Use Case: Optional Capability<\/h1>\n\n\n\n<pre class=\"wp-block-code\"><code>package main\n\nimport \"fmt\"\n\n\/\/ Required behavior.\ntype Saver interface {\n\tSave()\n}\n\n\/\/ Optional additional behavior.\ntype Closer interface {\n\tClose()\n}\n\ntype File struct{}\n\nfunc (File) Save() {\n\tfmt.Println(\"Saving file\")\n}\n\nfunc (File) Close() {\n\tfmt.Println(\"Closing file\")\n}\n\nfunc process(s Saver) {\n\n\t\/\/ Every Saver can Save().\n\ts.Save()\n\n\t\/\/ But maybe not every Saver can Close().\n\t\/\/\n\t\/\/ Check whether this particular value\n\t\/\/ also satisfies Closer.\n\tcloser, ok := s.(Closer)\n\n\tif ok {\n\t\tcloser.Close()\n\t}\n}\n\nfunc main() {\n\n\tfile := File{}\n\n\tprocess(file)\n\n\t\/\/ Output:\n\t\/\/\n\t\/\/ Saving file\n\t\/\/ Closing file\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The assertion:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>closer, ok := s.(Closer)\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">means:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\"Does the concrete value inside s\nalso support Closer?\"\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">18. Type Assertions Only Work on Interfaces<\/h1>\n\n\n\n<pre class=\"wp-block-code\"><code>package main\n\nfunc main() {\n\n\t\/\/ Normal string variable.\n\tname := \"Alice\"\n\n\t\/\/ This is INVALID:\n\t\/\/\n\t\/\/ name.(string)\n\t\/\/\n\t\/\/ Why?\n\t\/\/\n\t\/\/ name is already a string.\n\t\/\/ It is not an interface value.\n\n\t_ = name\n\n\t\/\/ --------------------------\n\n\t\/\/ This IS an interface.\n\tvar value any = \"Alice\"\n\n\t\/\/ Therefore a type assertion is allowed.\n\ttext := value.(string)\n\n\t_ = text\n}\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">19. Unsafe vs Safe Type Assertion<\/h1>\n\n\n\n<pre class=\"wp-block-code\"><code>package main\n\nfunc main() {\n\n\tvar value any = \"Go\"\n\n\t\/\/ ------------------------------\n\t\/\/ UNSAFE \/ ONE-VALUE FORM\n\t\/\/ ------------------------------\n\n\t\/\/ Use when you are certain.\n\ttext := value.(string)\n\n\t_ = text\n\n\t\/\/ If wrong:\n\t\/\/\n\t\/\/ runtime panic\n\n\n\t\/\/ ------------------------------\n\t\/\/ SAFE \/ TWO-VALUE FORM\n\t\/\/ ------------------------------\n\n\ttext2, ok := value.(string)\n\n\tif !ok {\n\t\t\/\/ Wrong type.\n\t\treturn\n\t}\n\n\t_ = text2\n\n\t\/\/ If wrong:\n\t\/\/\n\t\/\/ no panic\n\t\/\/ ok becomes false\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For learning and most uncertain data, prefer:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>value, ok := data.(Type)\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">20. Final Cheat Sheet<\/h1>\n\n\n\n<pre class=\"wp-block-code\"><code>package main\n\nfunc main() {\n\n\t\/\/ --------------------------------\n\t\/\/ Interface containing a string\n\t\/\/ --------------------------------\n\n\tvar value any = \"Go\"\n\n\n\t\/\/ --------------------------------\n\t\/\/ Basic type assertion\n\t\/\/ --------------------------------\n\n\ttext := value.(string)\n\n\t_ = text\n\n\n\t\/\/ --------------------------------\n\t\/\/ Safe type assertion\n\t\/\/ --------------------------------\n\n\ttext2, ok := value.(string)\n\n\tif !ok {\n\t\treturn\n\t}\n\n\t_ = text2\n\n\n\t\/\/ --------------------------------\n\t\/\/ Type assertion is NOT conversion\n\t\/\/ --------------------------------\n\n\t\/\/ Assertion:\n\t\/\/\n\t\/\/ value.(string)\n\t\/\/\n\t\/\/ means:\n\t\/\/\n\t\/\/ \"Is a string already inside value?\"\n\n\n\t\/\/ --------------------------------\n\t\/\/ Type conversion\n\t\/\/ --------------------------------\n\n\tnumber := 10\n\n\tdecimal := float64(number)\n\n\t_ = decimal\n\n\n\t\/\/ --------------------------------\n\t\/\/ Many possible types\n\t\/\/ --------------------------------\n\n\tswitch v := value.(type) {\n\n\tcase string:\n\t\t_ = v\n\n\tcase int:\n\t\t_ = v\n\n\tcase bool:\n\t\t_ = v\n\t}\n}\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">The One Definition to Remember<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ TYPE ASSERTION:\n\/\/\n\/\/ actualValue, ok := interfaceValue.(ExpectedType)\n\/\/\n\/\/ means:\n\/\/\n\/\/ \"Check whether the value stored inside this\n\/\/ interface has the type I expect.\n\/\/\n\/\/ If yes:\n\/\/     give me the value\n\/\/     ok = true\n\/\/\n\/\/ If no:\n\/\/     give me the zero value\n\/\/     ok = false\"\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">The Easiest Mental Model<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ Imagine:\n\/\/\n\/\/ var value any = \"Alice\"\n\/\/\n\/\/\n\/\/ value is a BOX:\n\/\/\n\/\/ +----------------------+\n\/\/ | Type:  string        |\n\/\/ | Value: \"Alice\"       |\n\/\/ +----------------------+\n\/\/\n\/\/\n\/\/ name, ok := value.(string)\n\/\/\n\/\/ means:\n\/\/\n\/\/ \"Open the box.\n\/\/\n\/\/ Is the value inside really a string?\"\n\/\/\n\/\/\n\/\/ YES:\n\/\/\n\/\/ name = \"Alice\"\n\/\/ ok   = true\n\/\/\n\/\/\n\/\/ NO:\n\/\/\n\/\/ name = \"\"\n\/\/ ok   = false\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>In one sentence:<\/strong> A <strong>type assertion checks or extracts the actual value\/type stored inside a Go interface.<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>1. What Is a Type Assertion? A type assertion is used when you have a value stored inside an interface and you want to check or retrieve&#8230; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1057","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/1057","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/comments?post=1057"}],"version-history":[{"count":1,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/1057\/revisions"}],"predecessor-version":[{"id":1058,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/1057\/revisions\/1058"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/media?parent=1057"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/categories?post=1057"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/tags?post=1057"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}