1

Sorry for the ambiguous title. I'm not getting a compiler error when I believe that I should, based on creating a new type and a function that takes an argument of that type.

The example:

package search

//Some random type alias
type Search string

//Takes a string and returns Search
func NewSearch(s string) Search {
   return Search(s)
}

//This is where things are getting weird
//Returns an int just for arbitrary testing
func PrintSearch(s Search) int{
    return 5
}

Now my assumption would be, if I created an object using NewSearch, I would be able to pass it to PrintSearch and have everything run as expected, but if I passed PrintSearch a primitive string, it should not compile. I am not experiencing this behavior.

The main code:

package main
import (
    "fmt"
    ".../search" //no need to type the whole path here
)

func main() {
   SearchTerm := search.NewSearch("Test")
   StringTerm := "Another test"

   fmt.Println(search.PrintSearch(SearchTerm)) // This should print 5
   fmt.Println(search.PrintSearch(StringTerm)) // This should throw a compiler error, but it is not
}

It seems like if I write the type and the function in the same package as main, everything works as I'd expect? As in, it throws a compiler error. Is there something I've missed about cross-package type coercion?

12
  • 5
    You don't need to convert the the type when it's assignable: golang.org/ref/spec#Assignability Commented Sep 27, 2016 at 2:15
  • So, what is the specific usecase for type Something string if you'd get the same type-safety from just using string itself? Commented Sep 27, 2016 at 2:28
  • 1
    "x's type V and T have identical underlying types and at least one of V or T is not a named type." I quote the doc JimB linked. Search underlying type is string and string is an unnamed type. Commented Sep 27, 2016 at 3:03
  • 3
    It is about the method set which is different. Using string as an example makes a very bad example here. Commented Sep 27, 2016 at 4:39
  • 1
    @thisisnotabus I've just repeated your example and I'm getting cannot use StringTerm (type string) as type a.Search in argument to a.PrintSearch. Are you sure you aren't using constants in your original code? Commented Sep 27, 2016 at 9:18

1 Answer 1

1

We can simplify this example a bit further (playground):

package main

type Foo string

type Bar int

func main() {
    var f Foo = "foo"
    var b Bar = 1

    println(f, b)
}

This is explained in the spec's assignability section.

A value x is assignable to a variable of type T ("x is assignable to T") in any of these cases:

  • x's type is identical to T.
  • x's type V and T have identical underlying types and at least one of V or T is not a named type.
  • T is an interface type and x implements T.
  • x is a bidirectional channel value, T is a channel type, x's type V and T have identical element types, and at least one of V or T is not a named type.
  • x is the predeclared identifier nil and T is a pointer, function, slice, map, channel, or interface type.
  • x is an untyped constant representable by a value of type T.
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.