I am creating a gRPC service using Proto 3 and C#.
In the Google developer guide for Protobuff it says about package:
In C# the package is used as the namespace after converting to PascalCase, unless you explicitly provide an option csharp_namespace in your .proto file.
So I'm not sure from that what's the difference between package and option csharp_namespace? What happens if I declare them both? If I declare one of them then is the other one redundant?
Packages are quite confusing in Protocol Buffers since people don't really see Protobuf as a language by itself. The protobuf package is useful for generation in your case (when you don't define csharp_namespace), but this is also useful within your proto files.
If you have:
a.proto
syntax = "proto3";
package my_package;
message A {}
in one file and you import this file in another which doesn't use the package, as so:
b.proto
syntax = "proto3";
import "a.proto";
message B {
my_package.A a = 1;
}
you will need to specify the fully qualified name (my_package.A).
Now, for option csharp_namespace. This will tweak the code generation and so that the namespace in your C# code is the one that you provided as value.
So, as for which one will prevail if you define both, it should be the option one since this is for tweaking the generation, where the package is more for you protobuf architecture.
The package name will be used to give a name to the generated service, and this name will be used to generate the URL, which will be invoked during the call
to the remote procedure.
e.g.
syntax = "proto3";
package gRPCDemo.v1;
option csharp_namespace = "Branch.Sample.gRPC";
service BranchService {
rpc GetById (CountrySearchRequest) returns (CountryReply) {}
}
so If a package name is not set, then the __ServiceName property will have the value of BranchService.
Related
Code like below
package internal
var internalVar = "foobar"
How can i access this internalVar from another package like package main?
internal package is placed in a 3rd party library, and my application needs to use some private info which original author is not willing to expose as a public API.
As #mkopriva mentioned, internal variables should not be accessed outside their packages at all. Go explicitly does that as a way to enforce accessibility and if the internal var is not exported, then it shouldn't be accessed. Again: don't do this, it's bad Go and we don't like it. Always export your variables when you need to access them outside your packages.
That huge disclaimer above being said, there are ways on how you can access internal variables: pointers, assembly and linkname. I'll explain the later since it's the easiest one:
Go compiler has this nifty directive called //go:linkname. It basically links variables/functions between different packages. From the documentation:
//go:linkname localname [importpath.name]
This special directive does not apply to the Go code that follows it. Instead, the //go:linkname directive instructs the compiler to use “importpath.name” as the object file symbol name for the variable or function declared as “localname” in the source code. If the “importpath.name” argument is omitted, the directive uses the symbol's default object file symbol name and only has the effect of making the symbol accessible to other packages. Because this directive can subvert the type system and package modularity, it is only enabled in files that have imported "unsafe".
That means that you can use it to access otherwise unexported functions and variables, with something like this:
main.go
package main
import (
"temp/test-access-internal/internal"
_ "unsafe"
)
//go:linkname message temp/test-access-internal/internal.message
var message string
func main() {
message = "abc"
println(message)
internal.SayHello()
}
internal/internal.go
package internal
var message string = "Hello!"
func SayHello() {
println(message)
}
You will see that the output respects the "abc" value we've overwritten.
Don't do this unless you really, really needs to monkey patch something.
Consider the following interface definition:
package repos
import (
resources "unit/pkg/resources"
)
type IRepo interface {
fetch(int32) (resources.IResource, error)
update(resources.IResource) (resources.IResource, error)
new() resources.IResource
create(resources.IResource) (resources.IResource, error)
delete(int32) error
}
Is there a way to 'use' the imported package (in the sense of C++ namespaces), so that I don't need to explicitly name it using dot notation each time I reference one of its types (IResource)
(TBH - this may just mean that IResource belongs in the repos package and not in resources)
You can prefix the import declaration with the name . to import all of its identifiers:
package repos
import (
. "unit/pkg/resources"
)
However, import . is almost never the appropriate solution. If new identifiers are added to the resources package in the future, they can collide with existing identifiers in the repos package and break your build.
Furthermore, the fact that the package name is redundant with the type name may indicate that either the package or the types within that package should have a better name (see the Package names blog post for much more detail).
In this case, perhaps the abstraction boundary between resources and repos is doing more harm than good. What kind of resources are you dealing with here? Could the Resource type be moved into some higher-level package?
Finally, I would note that the IRepo interface seems very large and likely out-of-place. Go interfaces — unlike, say, Java interfaces — generally belong with the API that consumes the interface, not the API that provides implementations of that interface.
For more on that principle, see:
https://golang.org/wiki/CodeReviewComments#interfaces
https://hyeomans.com/golang-and-interfaces-misuse/
https://dave.cheney.net/2016/08/20/solid-go-design
https://dave.cheney.net/practical-go/presentations/gophercon-israel.html#_prefer_single_method_interfaces
You can use a type alias.
type IRes = resources.IResource
In contrast to a type definition, an alias is just another name for the same type and not a new distinct type. A type definition would be without the =.
I'm trying to use the go/ast package to perform a source to source transformation on parts of a go program. One of my goals is to automatically generate from an interface definition with stylized comments, the definition of a struct that implements that interface. I have this program (https://github.com/MarkNahabedian/defimpl) working except that my present implementation doesn't always include in the output file those packages from the input file that are required by the output file.
The current implementation is a bit kludgy in how it determines what to import. Instead I'm tryiing to use ast.Walk to look for package references. My apparently nieve assumption is that any package refe3rence would appear as the X member of an ast.BinaryExpr. From instrumenting the code that generated this (contrived test) output though
// This file was automatically generated by defimpl from c:\Users\Mark Nahabedian\go\src\defimpl\test\code.go.
package test
import "reflect"
import "defimpl/runtime"
type ThingImpl struct {
node ast.Node
}
var _ Thing = (*ThingImpl)(nil)
func init() {
inter := reflect.TypeOf(func(t Thing) {}).In(0)
var impl *ThingImpl
runtime.Register(inter, reflect.TypeOf(impl))
}
// Node is part of the Thing interface.
func (x *ThingImpl) Node() ast.Node {
return x.node
}
I see that there are no BinaryExpr nodes in the AST. My question is: what is the AST node type of "ast.Node".
I wish that the documentation of the go/ast package provided a clear association between the interface and struct types it defines.
The expression ast.Node is a selector expression. The go/ast package represents the expression with the *ast.SelectorExpr type.
To understand how a language feature is represented in go/ast, parse a small program with the feature and dump the resulting tree. The spew package is a convenient tool for dumping the tree. Run an example on the playground.
In most Go programs I have seen, even those that have just one package, the names of types are written with a capital letter, which makes them exported.
Is this just a convention to make clear that they are types or is there a need for all types to be exported?
Initially I was going to put examples here of exported types, but looking around some popular Go projects I only found exported types so far. So any example of an unexported type in a reasonably large Go project would be welcome.
The type starting with an uppercase letter are exported to other packages. Those starting with a lowercase letter can be used only inside the package. Important note: it is possible to export an interface without exporting the struct that implements it.
It is not a convention to export types. Only export them if you allow them to be used outside the package. In the example you provided, there was no need to export the Server type, because it has no exported field or methods.
Export only the types that are part of the contract with the client. Exporting types that are only used internally is a mistake and is confusing in the documentation.
Edit:
A little clarification about the Server type. It implements the http.Handler interface (must define ServeHTTP(http.ResponseWriter, *http.Request) ), so it is possible to make it not exported and use the interface as the return type of NewServer function.
Types can be private.
Having a public function returning a private type however does not work. As long as the type is only used package internally, I keep it private.
EDIT:
In your example, Server has to be public because it is returned by public functions and thus used outside the package. The function NewServer returns *Server.
EDIT for new example:
In the new example this is the main package. It can't be imported anyway.
It's not a matter of convention, Go actually uses capitalization to determine which things are exported, i.e. available when you import the package.
E.g. if I have:
package a
const Exported = "hi"
const nonExported = "mom"
Then in a different package, you can import a.Exported but not a.nonExported:
package main
import "PATH/a"
func main() {
println(a.Exported)
// this won't compile
// println(a.nonExported)
}
I'm trying to simply use types (interfaces) from other commonjs modules. I'm wondering if there is a way to do this without having to import the module each time I need just the types (no implementation)?
Also to the same point. How would I use commonjs declared module types in projects without compiling with "--module commonjs"? (just to use the types, I'm aware you could do var x = require('x') if you don't care about type safety, but that defeats the purpose of TypeScript)
This seems like a valid use case as one could desire to create a library free from the actual implementation... But as I currently see it, you have to import x = require('x') on the actual implementation, even if I don't need it and already have the definition file.
Is there a way to tell the compiler that it "just exists," similar to how declare works with variables?
Example:
Suppose I have file.ts that I'm not compiling with any module setting (none):
/// <reference path="ExternalCommonJSModule.d.ts" />
export class A {
public foo(bar: ITypeFromExternalCommonJSModule): number {
return bar.x * 2;
}
}
And suppose ExternalCommonJSModule.d.ts looks like this:
declare module "ExternalCommonJSModule" {
export interface ITypeFromExternalCommonJSModule {
x: number;
}
}
(note, this doesn't compile because file.ts isn't compiled with --module commonjs and it doesn't import the implementation of the .d.ts)
I'm wondering if there is a way to do this without having to import the module each time I need just the types (no implementation)
You can put the interfaces in a global module e.g. globals.d.ts and then you would be able to use them throughout the project without importing.
Note: as soon as you global you are severely limiting the shareability of your code and opening yourself to the diamond version dependency problem.